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