java.lang.OutofMemoryError:unable to create new native thread

image.png

测试环境应用部署突然报错 unable to create new native thread

排查方向:
1、机器内存是否足够为新线程分配内存
2、创建线程数是否超过了操作系统的限制

线程在堆内存之外的内存上创建,所以如果分配了堆内存之后只剩下很少的可用内存,依然可能遇到java.lang.OutOfMemoryError: unable to create new native thread。
考虑如下场景:系统总内存6G,堆内存分配了5G,元空间512M。在这种情况下,JVM占用了5.5G内存,系统进程、其他用户进程和线程将共用剩下的0.5G内存,很有可能没有足够的可用内存创建新的线程。如果是这种情况,可考虑减小堆内存。

-Xss: 设置每个线程的栈容量。例如,-Xss128k 设置每个线程的栈大小为128KB。
如果设置的偏大,创建的线程较多,JVM创建新的线程无法申请足够内存,则会抛出OutOfMemoryError异常。
同时,如果设置太小,线程在运行过程中,线程的调用栈深度增加,JVM可能会抛出StackOverflowError。

排查过程:
1、通过free命令查看内存使用情况
2、通过ps -ef|grep java查看机器上运行的jvm示例,以及jvm启动参数
3、通过jstack 工具来确定Java应用创建了多少线程

jstack 输出会列出所有的线程信息。每个线程信息以 "线程名称" os_prio=优先级 tid=线程ID nid=本地线程ID 的形式开始。你可以通过计数这些行的数量来确定当前活动的线程总数。
如果想自动化这个过程,可以使用脚本来解析 jstack 的输出,并统计线程数量。例如,可以使用以下命令来统计:
ps -ef | grep java 在输出结果中找到你的应用程序对应的进程ID。
jstack {进程id如12345} | grep -c '^"' 这个命令会统计以双引号开头的行数,即线程的数量。

4、调整操作系统线程数阈值
操作系统会限制进程允许创建的线程数,使用ulimit -u命令查看限制。某些服务器上此阈值设置的过小,比如1024。一旦应用创建超过1024个线程,就会遇到java.lang.OutOfMemoryError: unable to create new native thread问题。如果是这种情况,可以调大操作系统线程数阈值。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容