jvm问题排查一直没有自己的思路体系,这次测试环境发现了一个cpu飙高的问题,刚好用来实践一次,纸上得来终觉浅,绝知此事要躬行。最后捋一下思路和过程,记录
定位java进程
linux, top 命令,发现 23071进程cpu,内存均占比很高
排查cpu问题,对于jvm如何排查cpu占用?当然是要找到具体的内部线程
查看进程内的线程资源占用
使用命令,top -Hp 23071,
发现这些线程cpu占用很高,想要知道这些线程的信息,则必须借助jstack命令,而jstack中的线程号是十六进制的,故需将线程号转为16进制的,以线程23081为例
使用命令 printf "%x\n" 23081,得到结果 5a29,下一步则是使用jstack命令查询线程详细信息
定位jvm线程信息
使用命令,jstack 23071 > 23071.txt,将信息输出
查找 5a29的线程信息
线程cpu飙高原因排查
结果,这是一个cms垃圾回收线程,其他的23082,23083也是5a2a等垃圾回收进程,说明jvm在进行频繁的垃圾回收,内存出问题了(前面已经说了,废话)
GC情况查看
如何查看gc情况?当然是jstat
使用命令jstat -gc 23071
注意FGC 5757次,事件2977.424秒(各个参数的含义和单位可以百度),每次回收0.5s这个已经延迟很高了,此java进程启动不到2天,说明老年代有大量对象无法回收,频繁触发fullgc
堆内存问题定位
内存问题,如何看?先看大致的内存使用,当然是jmap命令,注意(这个会jvm暂停,线上慎用,线上怎么办?)
先查看堆使用信息,jmap -heap 23071 > 23071heap.txt
此java进程使用的是cms垃圾回收器,concurrent mark-sweep generation,代表的是老年代,说明有大量的老年代对象无法回收,下一步则是查看那些对象一直无法回收
还是使用jmap -histo:live 23071 > 23071map.txt,SensorData对象示例一千多万个,定位到此处,应该去排查对应的程序逻辑了。
体会
1.jvm就像个黑箱子,我们发现问题时,需要借助系统命令、jvm工具命令去不停的刺探,按图索骥发现最终的原因,
2.排查次数多了,自己对jvm问题排查的方法和体系就自动建立了