使用jstack工具排查JVM中CPU高消耗问题
确认CPU消耗情况:
- 使用操作系统的监控工具确认哪个Java进程导致CPU高消耗。
- Unix/Linux:
top
或htop
- Windows: 任务管理器
- Unix/Linux:
- 使用操作系统的监控工具确认哪个Java进程导致CPU高消耗。
找到Java进程PID:
- 通过找到Java进程的PID,为后续的jstack和其他分析提供依据。
- Unix/Linux: 在
top
或ps
命令中可以看到PID。 - Windows: 任务管理器中或者使用
jps
命令。
- Unix/Linux: 在
- 通过找到Java进程的PID,为后续的jstack和其他分析提供依据。
分析线程CPU消耗:
- 找出哪个线程消耗了大量的CPU。
- Unix/Linux:
top -H -p
或ps -mp -o THREAD,tid,time
- 将线程ID转换为十六进制(因为jstack输出的线程ID是十六进制的),例如:
printf "%x " <THREAD_ID>
使用jstack获取线程Dump:
- 使用
jstack
工具获取线程堆栈信息:jstack -l <PID> > threaddump.txt
- 使用
分析线程Dump:
- 打开生成的
threaddump.txt
文件,找出之前高CPU消耗的线程ID对应的堆栈信息。搜索对应的十六进制线程ID(例如:0x2a),通常每个线程会以如下格式开头:"Thread-1" #2 prio=5 os_prio=0 tid=0x00007f8e99800000 nid=0x2a runnable [0x00007f8e8b8f7000]
- 打开生成的
理解线程堆栈信息:
- 分析该线程的调用栈,特别关注状态为
runnable
的线程。 - 观察调用栈中的方法,查看是否有业务逻辑、死循环、资源争用等。
- 分析该线程的调用栈,特别关注状态为
进一步分析和解决问题:
- 找到具体的代码位置,结合代码逻辑分析问题原因。
- 结合其他监控工具(如VisualVM、JConsole等)进行更深入的分析,查看线程、内存、GC活动等。
采取措施:
- 根据分析结果进行相应的优化,比如修正代码中的死循环、改进算法、调整并发策略等。
示例
假设已经找到高CPU消耗Java进程的PID为1234,并且对应的高CPU消耗线程ID为4567:
获取高CPU线程的十六进制ID:
printf "%x " 4567
使用jstack获取线程Dump:
jstack -l 1234 > threaddump.txt
在
threaddump.txt
中搜索0x11d7
(假设转换结果为0x11d7)。