使用 top 命令查看高CPU进程,执行命令后可以按 1 键查看各CPU 内核负载情况。CPU使用率主要看us、sy两个指标。

假设 10760 是一个高CPU的进程。
使用 top -H -p 查看 10760 的线程信息
top -H -p 10760

TIME列就是各个Java线程耗费的CPU时间。
以线程ID 10952的线程为例进行排查,将10952 转为16进制。后面排查日志时使用。
printf "0x%x\n" 10952

会得到10952的十六进制0x2ac8。
用jstack来输出进程ID 10760的堆栈信息,然后根据线程ID 10952的十六进制值0x2ac8 grep,如下:
jstack 10760 | grep 0x2ac8

可以看到CPU消耗在mysql-cj-abandoned-connection-cleanup这个类的Object.wait()。具体可以去代码中查看这个方法的实现,排查问题。
除了第4步,也可以将当前进程的所有堆栈信息导出,下载下来再分析。
jstack -l 10760 >> jstacklog.txt

下载jstacklog.txt到本地,搜索 0x2ac8 ,可以看到更详细的堆栈信息。

总结
上面的几个步骤演示了jstack命令的使用,不是一个实际的问题排查记录。在实际问题排查中,可能要反复查询第2步中列出的多个线程,再根据程序代码情况,综合判断出问题所在。