您的位置:首页 > 运维架构 > Linux

Linux环境下使用JVM诊断工具排查问题

2016-09-21 15:44 537 查看
刚接手的服务经常间断性的出现CPU突然爆高的情况,正常情况下java应用线程的CPU利用率在200%左右,但是在出问题的时候利用率接近2000%(部署的服务器为单机24核)。开始由于对项目不太熟悉,所以一直怀疑是流量的问题,但是通过日志观察,问题爆发的时候流量并没有多大波动,显得很正常。最后随着时间的推移,慢慢的用了一些JVM自带的诊断工具来追踪问题,这里整理一下排查思路。

1.首先是top命令观察服务器总体的运行情况。最主要的参数有Cpu,负载(load),内存(Mem)



很明显,通过截图(本截图显示top命令,然后按1键可以看到各核信息)可以看出,java进程异常,服务器负载过高。所以再通过top -p pid -H命令查看该java进程的线程状况,如图(此贴为整理贴,所以有公司及其截图和本人电脑截图,风格不一样,且各个命令直接没有连续性,但最终目的是记录总结一种思路,请各位看官见谅):



从上截图也可以查看,多个线程的CPU接近100%,很是异常。而且通过一段时间观察,发现这几个线程的生命周期很长,没有及时消亡,很是异常。

2.遇到Cpu这种情况,很多问题来自于线程,所以可以通过jstack -l pid(java线程id) > file.stack命令输出线程栈信息(输出成文件是为了更好的进行查找等各项操作)。通过线程栈信息,首先我们可以快速的知道是否有死锁。如果没有,通过java进程的线程pid,比如上图中的pid
17402线程,将17402转换为16进制:43fa,然后拿43fa去文件中搜索,看最终问题出在哪里。



通过截图,我们可以知道问题出在在多线程场景下使用了非安全性的jdk类TreeMap,多个线程在put的时候由于红黑树的插入出现死循环(这个问题在stackOverFlow上面也有)。在这里开始把出问题的根源放在这个地方,在后续几次爆发时再次观察到这种情况后提交给相关同事修改,上线,至此问题解决,再无此问题出现。

当然一开始使用的使用的时候并没有这么顺,需要不断积累。在问题排查的时候还是有一些别的常用命令,这里我列举一下:

1).java各对象大小:jmap -histo pid | jmap -histo:live pid
2).jvm gc信息:jstat -gcutil pid 1000(间隔1000ms) 100(总共输出100次)

3).触发java dump命令:jmap -dump:format=b,file=/home/longhao/heamdump.out pid 分析工具:MAT Eclipse(这个为内存分析,我也没试过,相对于1)会更详细具体一些,在内存溢出的时候可以用上)

总结整个排查过程其实就是Linux命令使用以及JVM自带诊断工具的使用,在查过几次之后基本上就能够熟悉了,最后附上官网学习链接,此贴整理排查思路,JVM诊断工具命令的学习建议还是到官网。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/toc.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm linux