jvm问题排查总结

一: 问题背景与现象

   1、健康检查失败

   2、接口测试反应慢

   3、系统多次CPU或内存使用率飙升,且是java进程引起

二: 解决问题思路   

1.确定服务已部署成功且没有被回收健康状态检查成功,打开终端控制面板,登录服务器,若不能直接登录则先登录跳板机再登录服务器,执行jps命令查看服务进程是否还存在

2.执行top命令查看CPU和内存使用率。若发现有一或多个CPU或内存的使用率居高不下(例如80%~100%),且是Java相关进程引起的,若不是则排查其他问题,如系统问题。q退出top,top使用详解

3.执行top -Hp ${pid}  (步骤2中cpu或内存使用率过高的Java进程号)。若是接口反应慢问题,则可在此时请求接口,观察得到持续占用CPU或内存使用率过高的线程号(用于后续步骤5)。    

    3.1、若cpu使用率过高,执行jstack ${pid} > jstack.log   (步骤2中pid进程号)。得到该Java进程的线程快照jstack.log。

         3.1.1、执行less jstack.log ,将之前有问题的(步骤3中)线程号转换为16进制,在线程快照中查找到该线程,输入: /16进制线程号  enter  ,查看其线程相关信息,

                    查找与本服务密切相关的信息(如自定义类),确定问题所在行,解决问题,重试。

                    若发现是JVM的垃圾回收线程。再搜索整个文件,没有被死锁的线程。于是怀疑内存没有正确释放,JAVA进程已使用的内存,已经达到了分配给JVM的最大内存。导致垃圾回收频                      繁执行FullGC,占用了CPU。

                    执行jstat -gcutil ${pid} 若发现年轻代,老年代内存使用率太高。进一步证实之前的怀疑。jstat使用详解 

     3.2、若内存使用率过高,执行jmap -histo:live ${pid}  | head -10 ,若还不能确定造成内存泄漏的类, 则执行jmap -dump:format=b,file=${dumpFileName} ${pid} 得到当前内存快照。jmap使用详解

4. 使用eclipse的memory analyzer导入内存快照,进行分析。找出内存异常的对象。

5. 修改程序的BUG。

6. BUG修复以后,继续定时获取内存快照,持续观察。直到彻底解决问题。

三、 解决问题的实践过程

登录跳板机,再登录服务器,例如:

ssh [email protected]

password: xxxx

ssh 10.247.3x.xx

  (3) top 命令查看 %cpu %mem   (正常状态)

  (4) 测试接口复现问题 确定消耗资源较大的进程 pid

 测试接口:http://hostxx/nxschema/api/v1/type/mysql/catalog/plus_table_test/entity/T_MailInfo

  此时top:可以看出pid为4083的进程占用cpu资源较大

  

  (5) top -H -p 4083 找出进程4083中消耗资源最大的线程pid 第一条记录pid为21181

  

  (6) 将进程4083的所以线程信息存入jstack.txt  查看与线程21181相关的信息

       jstack -l 4083 > jstack.txt 

       less jstack.txt

       /52bd (将pid 21181转换为16进制52bd)

      查看记录中与本线程52bd有关的记录 确认问题所在行

猜你喜欢

转载自blog.csdn.net/qq_35119422/article/details/81225611