记录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




目录
相关文章
|
机器学习/深度学习 移动开发
解决mqtt连接报Connection lost (32109) - java.lang.IllegalArgumentException: Invalid UTF-8 char: [a]错误问题
最近生产环境在向mqtt客户端发布数据时反复出现一会断开一会连接错误,捕获的异常是java.lang.IllegalArgumentException: Invalid UTF-8 char: [a]。尝试各种方式都未找到问题的原因,最后在检查发送主题topic的时候发现所发送mqtt客户端的topic的结尾包含了换行符,最终才将问题得以解决。
6688 0
解决mqtt连接报Connection lost (32109) - java.lang.IllegalArgumentException: Invalid UTF-8 char: [a]错误问题
|
NoSQL Redis
Redis集群(六):集群常用命令及说明
Redis集群(六):集群常用命令及说明
809 0
|
Arthas 监控 Java
阿里arthas(阿尔萨斯)的linux安装和使用
转自https://blog.csdn.net/SDJN_ONE/article/details/123198219
1588 0
阿里arthas(阿尔萨斯)的linux安装和使用
|
SQL 监控 关系型数据库
【MYSQL高级】Mysql找出执行慢的SQL【慢查询日志使用与分析】
【MYSQL高级】Mysql找出执行慢的SQL【慢查询日志使用与分析】
6795 0
|
Docker 容器
Docker部署minio-arm64版本,阿里官方推荐
Docker部署minio-arm64版本,阿里官方推荐
|
Java Linux iOS开发
8 种 Java- 内存溢出之五 -Unable to create new native thread
8 种 Java- 内存溢出之五 -Unable to create new native thread
|
安全 Java 网络安全
如何在Java中处理SSLHandshakeException异常?
如何在Java中处理SSLHandshakeException异常?
2809 1
|
SQL 监控 搜索推荐
Elasticsearch 与 OpenSearch:开源搜索技术的演进与选择
Elasticsearch 与 OpenSearch:开源搜索技术的演进与选择
|
消息中间件 存储 Kafka
【Kafka】Kafka 的日志保留期与数据清理策略
【4月更文挑战第13天】【Kafka】Kafka 的日志保留期与数据清理策略
|
人工智能 Java
通过okhttp调用SSE流式接口,并将消息返回给客户端
通过okhttp调用SSE流式接口,并将消息返回给客户端

热门文章

最新文章