java.lang.OutOfMemoryError:未能创建线程错误

我为什么要这样做,我该怎么改正呢?

症状

我尝试运行脚本/启动产品服务,但由于 OutOfMemoryError 异常,环境无法为其创建 Java 线程。

原因

当系统没有足够的资源来创建新线程时,会出现 java.lang.OutOfMemoryError: Failed to create a thread 消息。 此消息有三个可能的原因:
  • 用户/应用程序资源不足。
  • 系统已耗尽本机内存以用于新线程。 线程需要本机内存用于内部 JVM 结构,Java 堆栈和本机堆栈。
  • 已在运行的线程过多,系统已耗尽内部资源以创建新线程。
样本错误堆栈:
java.lang.OutOfMemoryError: Failed to create a thread: retVal -1073741830, errno 11
        at java.lang.Thread.startImpl(Native Method)
        at java.lang.Thread.start(Thread.java:891)
        at java.util.concurrent.ThreadPoolExecutor.addIfUnderMaximumPoolSize(ThreadPoolExecutor.java:738)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:668)
        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:396)
        at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:353)
        at java.lang.Thread.run(Thread.java:738)
注: 本机堆或系统堆与 Java 堆不同。 Java 堆包含 Java 对象的实例,并由垃圾回收维护。 在 JVM 启动期间, Java 堆的最大大小预先分配为一个连续区域,即使最小堆大小设置更低。 同时,本机堆是通过使用操作系统的底层 malloc 和自由机制来分配的,并用于 Java 对象的底层实现。 我们可以通过改变 Java 堆的大小来增加或减少可用的最大本机堆。 发生堆之间的这种关系,因为 Java 堆未使用的进程地址空间可用于本机堆使用率。

解决问题

请参阅以下(顺序)以更正此错误:
  1. Linux 具有每个用户限制的最大允许进程数,我们可以使用 ulimit -u 命令进行检查。 如果此值很低(缺省值为 1024),那么请将其无限或将其提升至高值,即 131072。 在ulimit-u输出中,该部分也作为max user processes部分突出显示。 使用以下命令将其设置为无限制: ulimit -u unlimited
  2. 通过使用 -Xmx 选项,通过降低 Java 堆的大小来增加可用本机内存量。 Java 堆未使用的进程地址空间可用于本机堆使用率。 Java 堆在 6 服务的 $TOP/bin/conf/service_mem_settings.ini 文件中设置,在后端脚本的 $TOP/bin/conf/env_settings.ini file 中设置为 custom_java_options
  3. 使用 df -k 命令检查空间需求。
  4. 降低正在使用的线程数。