JVM性能问题排查方法(使用jstack, jmap)
在生产环境中,当服务出现性能问题时,如:线程数异常、负载升高,如何快速定位问题,本文梳理一下大致思路及步骤。
通常我们需要首先定位问题线程,找到占用资源较多的线程号,然后才能针对该线程进行分析。
1.查看当前Java进程号
登录服务器,执行命令:
$ps aux | grep {service-name}
查看到目标进程号,如图所示目标服务的进程号为19083
2.使用Java进程号查看线程资源占用情况
执行命令:
$top -Hp {pid}
TIME列是各个线程耗费的CPU时间,占用时间最长的线程号是19228
3.查看线程的栈信息
将线程id转换为16进制,以便后续查看该线程的栈信息:如下转换得到4b1c
$printf %x 19228
执行以下命令查看当前线程对应的栈信息
#注意:一般线上环境启动Java程序用户与当前登录用户可能不一致,需要sudo权限 $sudo -u username /home/username/jdk/bin/jstack {pid} | grep {thread_id}
4.查看堆内存状态
首先可查看堆内存对象数据、大小信息。执行命令:
$sudo -u username /home/username/jdk/bin/jmap -histo:live {pid} | more
可查看当前堆内存中存活对象的统计信息,若某些对象数量过大、占用内存过高,则可能存在问题。
5.导出堆内存进行分析
还可将堆内存快照生成转储文件,进行分析。执行命令:
$sudo -u username /home/username/jdk/bin/jmap -dump:format=b,file=dump_file_name.hprof {pid}
生成转储文件后,可使用jvisualvm等工具进行分析。