后续如果在出现java.lang.OutOfMemoryError: unable to create new native thread
可以通过以下步骤进行处理(pid都是代表的出问题的线程ID):
jmap -heap pid 获取当前现成的jmap堆信息,对比第四步中的剩余RAM
jstack -l pid > 1.txt 将当前线程堆栈信息输出到文本1.txt,拷贝出来
ulimit -u/-a 查看系统当前用户最大连接数,如果不够,调整
free -m 查看当前系统的剩余总量,因为jvm的线程系统调用都是通过系统内核调用的,需要查看当前RAM的剩余空间是否足够支持继续创建线程
cat /proc/loadavg 第四个参数,第一位表示目前活动的cpu(小于或等于cpu数量),第二位表示后续等待执行的线程
ps -elfT | wc -l 查看当前服务器的所有线程数
ps -p pid -lfT | wc -l 查看当前PID的所有线程数
java -XX:+PrintFlagsFinal -version | grep ThreadStackSize 查看当前jvm中每个新建的线程需要占据多少内存,jdk8默认一个线程1M,如果此值过大,可以启动的时候通过jvm参数 -Xss128K 指定大小,或者新增机器内存
需要打印异常后的dump文件,所以jar包启动方式如下:java -Xms1024m -Xmx2014m -Xmn512m -XX:SurvivorRatio=8 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump/dump.hprof dump.HeapOOM
对应含义
-Xms:堆初始大小
-Xmx:堆最大值
-Xmn:新生代大小(老年代大小=堆大小-新生代大小)
-XX:+HeapDumpOnOutOfMemoryError:发生内存溢出时生成heapdump文件
-XX:HeapDumpPath:指定heapdump文件
生产情况,优先执行第二步骤,需要dump文件分析当前的线程情况,其余的可以按优先级执行134678
如何分析定位cpu飙高的相关步骤:
- top 找出cpu占比最高的pid
- ps -mp pid -o THREAD,tid,time 打印出当前pid中占用最大的线程号
- printf "%x\n" tid 转换为16进制
- jstack pid | grep tid -A 30 在对应的jstack日志中查找对应的堆栈详细信息,根据实际情况定位处理