java.lang.OutOfMemoryError: unable to create new native thread无法创建本地线程分析

来源:互联网 发布:恒温花洒 知乎 编辑:程序博客网 时间:2024/05/16 15:44

此次应用出现OOM异常分析如下

 

1.        现象:

Caused by: java.lang.OutOfMemoryError:unable to create new native thread

 atjava.lang.Thread.start0(Native Method)

 atjava.lang.Thread.start(Thread.java:714)

 at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:949)

 atjava.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1371)

 

2.        现象解释:

无法创建本地线程

 

3.        tomcat的jvm配置

JAVA_OPTS="-server –Xms1024m –Xmx1024m-XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"

 

4.        参数解释

-Xms  JVM堆初始化值

-Xmx  JVM堆最大值

-XX:PermSize JVM方法区(永久代)值

-XX:MaxPermSize JVM方法区(永久代)最大值

-XX:MaxNewSize JVM堆区新生代最大值

-Xss 每个线程栈的大小,默认1M

 

5.        主机应用情况

主机上部署5个tomcat应用,主机内存8G

 

6.        分析情况

 

根据OOM异常信息:无法创建新的本地线程得知是本地线程无法满足现有应用的使用。线程的内存分配属于栈区,栈区的大小是动态变化的,是系统内存在分配完给jvm及自己系统保留运行内存后的剩余的可用大小。由于我们设置的–Xms1024m,所以5个tomcat应用所占的内存值为5G,保守估计系统保留500M运行内存,此时内存值剩余8-5.5=2.5G.所以目前只剩余2.5g内存供创建线程使用,根据-Xss默认为1M的线程栈大小得出可创建2500多个线程。均分到5个应用中,每个应用可创建的平均线程数为500个。

在生产上命令ps hH p <pid> | wc -l查看了正常运行下的应用的进程的线程数为375个。正常情况下线程数为平均值的75%。所以在偶发高峰期是很有可能达到极限的值。

 

 

 

 

7.        解决方法

 

 既然可创建的线程数不是很够,那就加大可创建的线程数。

 从分析中得知可创建的线程数的影响因子有三个:系统的内存、tomcat应用的内存-Xms及-Xmx、线程大小-Xss。得出四个方案可选。

 

一、                    将tomcat应用的-Xms1024堆区初始大小减小,比如减为-Xms 512,这时tomcat启动占的总内存为2.5g,从而节省出2.5g给线程使用,线程多出2500个。但是随着程序的运行和访问量加大,tomcat堆区的占用内存会向-Xmx1024靠拢,当都达到最大值1024,这时同样会出现只剩2.5g给创建本地线程使用。所以这时需要看应用的gc情况得出使用堆区的大小以估算未来一个使用情况,再考虑此种方案。

二、                    将线程大小-Xss默认值1M减小改为设定值512kb。这样线程数从以前的2500个加倍到5000个。考虑目前系统的方法不是很复杂,每个线程给512kb的大小还是足够的,所以此种方法比较好。

三、                    将系统内存加大,比如加个4g,线程数就可增加4000多个。这种方法最好,但是要钱去买内存。

四、                    把5个应用部署到2台或者3台主机上,这样就不仅是线程数增加,程序的处理能力也加强,当然这更费钱。

 

 

 

 

阅读全文
0 0
原创粉丝点击