一致以为是JVM内存分配不合理导致的,实际则不是。
排查过程:
1. `top`
查一下耗CPU的线程,执行top命令,可以看到CPU使用情况。
2. top -Hp 进程号
查看java进程下的所有线程占CPU的情况.
3.printf "%x\n" 线程ID
后续查看线程堆栈信息展示的都是十六进制,为了找到咱们的线程堆栈信息,咱们需要把线程号转成16进制。
例如,printf “%x\n” 线程ID ,打印:16b1,那么在jstack中线程号就是16b1
4. jstack 进程号 | grep -A 10 线程ID
执行 jstack 进程号 | grep 线程ID 查找某进程下 ,线程ID(jstack堆栈信息中的nid)=0xa的线程状态。如果"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0x16b1 runnable,第一个双引号圈起来的就是线程名,如果是“VM Thread”这就是虚拟机GC回收线程了
这个可以打印出异常信息,可以从异常信息,去找业务系统层面的错误。
5. jstat -gcutil 进程号
统计间隔毫秒 统计次数(缺省代表一直统计),查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大-》确认Full GC! 也可以使用jmap -heap 进程ID查看一下进程的堆内从是不是要溢出了,特别是老年代内从使用情况一般是达到阈值(具体看垃圾回收器和启动时配置的阈值)就会进程Full GC。
查看JVM工具:
arthas
download https://arthas.aliyun.com/doc/quick-start.html
解压后执行:
java -jar arthas-boot.jar
会提示你选个进程,输入数字即可
再输入dashboard
退出输入stop