记录unable to create new native thread 问题排查解决

简介: 解决 java.lang.OutOfMemoryError: unable to create new native thread

问题描述

image.png

系统部署后遇到这个问题,因该环境提供的服务器配置偏低导出出现 java.lang.OutOfMemoryError: unable to create new native thread异常

问题分析

问题本质原因是项目创建了线程,而系统能创建的线程数是有限制的,导致了异常的发生。能创建的线程数的具体计算公式如下:

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

当创建线程时虚拟机会在JVM内存创建线程对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生 java.lang.OutOfMemoryError: unable to create new native thread

问题解决

修改linux 最大进程数

1.查看用户打开到最大进程数

ulimit -a

max user processes    (-u) #系统限制某用户下最多可以运行多少进程过线程

2.修改进程数

1.在/etc/security/limits.conf 文件里添加如下内容

* soft nproc 65535      #打开进程数

* hard nproc 65535     #打开进程数

操作方法:

echo "* soft nproc 65535"  >> /etc/security/limits.conf

echo "* hard nproc 65535"  >> /etc/security/limits.conf

在 /etc/sysctl.conf 中添加 kernel.pid_max = 65535

# vim /etc/sysctl.conf

kernel.pid_max = 65535

或者

echo "kernel.pid_max = 65535" >> /etc/sysctl.conf

然后重启机器。

保存退出,输入以下命令执行使其生效  

其他问题排查

1.如果程序中有bug,导致创建大量不需要的线程或者线程没有及时回收,那么必须解决这个bug,修改参数是不能解决问题的。

2.如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:

MaxProcessMemory 使用64位操作系统

VMMemory 减少 JVMMemory 的分配

ThreadStackSize 减小单个线程的栈大小

3.优化代码里面的线程池的线程配置,减少 JVMMemory 的分配

思考问题

具体的排查方法

1:通过堆栈信息,确定是否存在创建线程过多的问题

创建了多少线程?过度创建的线程的堆栈信息是什么?谁创建了这些线程?

一旦了解清楚,就能很快解决OOM的问题

2:增加操作系统的线程数

通过ulimit -a查看操作系统的最大线程数,这里假设为1024

如果应用程序所需的线程数超过1024,可以通过增大操作系统的线程数解决问题

3:增加机器内存

如果发现操作系统的线程数并未达到上限,说明应用程序需要更多的内存来创建线程

此时,增加机器内存便可以解决问题

4:减少JVM堆内存(-Xmx)

增加机器内存涉及硬件操作,不是最佳的选择

这时,不要忘记:线程不是在JVM的堆内存中创建的!

如果为JVM分配堆内存后,剩余内存较少,也会导致OOM: unable to create new native thread

在JDK 1.8中,需要减少–Xmx配置的值;在JDK 1.7中,需要减少堆内存和永久代内存( –Xmx和-XX:MaxPermSize)

5: 减少进程数

减少进程数,与较少堆内存相似

如果Java进程数过多,即使每个进程使用的堆内存不大,但累积起来也会导致剩余内存较少,从而出现OOM: unable to create new native thread

6: 减少线程栈大小(-Xss)

如果每个线程的堆栈较大,应用程序整体消耗的内存也会变大

可以根据实际情况,减少线程的堆栈大小,即通过–Xss设置线程堆栈为一个合理的、较小值

注意:-Xss不是设置得越小越好,过小的-Xss值会导致应用程序出现java.lang.StackOverflowError错误,甚至都无法启动JVM




目录
相关文章
|
2月前
|
Java Linux iOS开发
8 种 Java- 内存溢出之五 -Unable to create new native thread
8 种 Java- 内存溢出之五 -Unable to create new native thread
|
3月前
|
机器学习/深度学习 Java Android开发
记录一个Flutter运行的异常FAILURE: Build failed with an exception. What went wrong: A problem occurred config
记录一个Flutter运行的异常FAILURE: Build failed with an exception. What went wrong: A problem occurred config
46 0
|
开发工具 Android开发
解决bug:运行项目时报异常 “Can't create handler inside thread that has not called Looper.prepare()”
解决bug:运行项目时报异常 “Can't create handler inside thread that has not called Looper.prepare()”
873 0
|
8月前
|
Unix Java Linux
Runtime.exec方法之获取process id
Runtime.exec方法之获取process id
148 0
|
11月前
|
数据库
11g health monitor新特性 DBMS_HM.RUN_CHECK
11g health monitor新特性,DBMS_HM.RUN_CHECK一例
|
Java jenkins 应用服务中间件
Jenkins部署异常:TomcatManagerException: FAIL - Unable to delete
Jenkins部署异常:TomcatManagerException: FAIL - Unable to delete
255 0
|
Java Apache
CDH: unable to create new native thread
发现问题 CDH-4.7.1 NameNode is down 启动NameNode报错如下,无法创建新的线程,可能是使用的线程数超过max user processes设定的阈值 2018-08-26 08:44:00,532 INFO org.
2484 0
|
Oracle 关系型数据库 Linux
oom_kill_process造成数据库挂起并出现found dead shared server
这篇博客是上一篇博客Oracle shutdown immediate遭遇ORA-24324 ORA-24323 ORA-01089的延伸(数据库挂起hang时,才去重启的),其实这是我们海外一工厂的遇到的案例,把内容拆开是因为这个case分开讲述显得主题明确一些。
1272 0
|
容器 分布式计算 Hadoop

热门文章

最新文章