jstack 工具
jstack (Stack Trace For Java)命令用于生成当前时刻的线程快照(一般称为 Thread Dump文件)
线程快照就是当前虚拟机每条线程正在执行的方法堆栈集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的原因。
线程出现停顿就可以通过 jstack 来查看各个线程调用的堆栈信息,就可以知道没有相应的线程在做什么,或者在等待什么资源。
问题描述
CPU 某些进程占用过高,导致服务器卡死,程序假死,进行问题排查。
产生原因
代码里有线程间死锁、死循环、请求外部资源导致的长时间挂起;
代码中有死循环或接近死循环的操作;
快速创建大量临时文件变量,导致频繁触发 GC 回收;
问题解决方法
1.通过 top -c 命令找到 CPU 占用率最高的进程 pid
top -c
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SsBkgZKj-1668417668866)(b810167186ff66fbfa7114827f349d14.png)]
2.top -Hp pid 命令找到该进程下 CPU 占用最高的线程(shift + p 按照 cpu 排序,shift + m 按照内存排序)
top -Hp pid(进程号)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pc4fxmoL-1668417668868)(ecf40114d166d44c84b2346fafc85980.png)]
3.使用 printf ‘%x\n’ pid (pid 为上一步骤中获取的线程号)将线程号转成16进制
jstack 工具导出的信息里面线程对应的nid是十六进制的
printf '%x\n' pid(进程号对应的线程号)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-toRndEiy-1668417668869)(45589e76487229bcf637d2dd8a8463ac.png)]
4.使用 jdk 自带工具 jstack 来排查问题
jstack -l pid(进程号) | grep (进程号对应的十六进制线程号)-A 80
pid(进程号)是指第一步 top -c 命令查找到的 cpu 占用最高的进程 id;
nid(进程号对应的十六进制线程号)是指该进程下 cpu 占用率最高的线程 id;
-A 80 是关键字后的80行代码
5.导出进程错误信息
jstack -l pid(进程号) > /tmp/stack_log.log
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d9Y4p4NL-1668417668870)(c90437e666d11888ff9952e31275bfde.png)]
6.查看错误信息
vi /tmp/stack_log.log
根据步骤3中的十六进制的进程号搜索问题
如若提示未找到 jstack 命令,请安装 java jdk 并配置 java 环境变量。