jstack 是 JDK 自带的线程堆栈分析工具,用于抓取 thread dump 以排查死锁、阻塞和 CPU 飙升等问题;需先用 jps -l 获取 PID,再用 jstack -l 采集带锁信息的快照,结合 top 定位高 CPU 线程并分析其栈轨迹。

jstack 是 JDK 自带的线程堆栈分析工具,能快速抓取 Java 进程的线程快照(thread dump),对排查死锁、线程阻塞、CPU 飙升等运行时问题非常有效。关键不在于“会不会用命令”,而在于“抓得准、看得懂、定位快”。
一、先确认目标进程 PID
排查前必须知道 Java 进程 ID:
- 常用命令:jps -l(列出所有 Java 进程及其主类或 JAR 路径)
- 若进程名不明确,可结合 ps aux | grep java 或 jps -lv 查看完整启动参数
- 注意区分多个 Java 进程,避免 dump 错误的实例
二、用 jstack 抓取线程快照(重点技巧)
基础命令是 jstack [pid],但实际使用要注意以下几点:
- 普通 dump:jstack 12345 > threaddump.txt(重定向保存,方便后续分析)
- 加 -l 参数:显示详细锁信息(对查死锁必备)→ jstack -l 12345
- 加 -e 参数(JDK 8u60+):打印每个线程的 native 堆栈(有助于分析 JNI 或 IO 阻塞)
- 生产环境慎用 -F(强制 dump):仅当目标进程无响应时使用,可能引发短暂 STW,且结果不一定完整
三、快速识别死锁(jstack 自带检测)
jstack 在 dump 结尾会自动检查并打印死锁摘要(前提是用了 -l):
- 如果存在死锁,你会看到类似:Found 1 deadlock.,紧接着列出互相持有/等待锁的线程及锁对象
- 重点关注 "waiting to lock" 和 "locked" 的对应关系,确认锁顺序是否成环
- 即使没触发自动检测,也可搜索 java.util.concurrent.locks 或 monitor entry,比对线程状态与锁地址
四、定位 CPU 飙升线程(结合 top + jstack)
CPU 高通常由某个或某几个线程持续执行引起,需联动分析:
- 先用 top -Hp [pid] 查看进程中各线程的 CPU 占用(按 P 排序),记下高 CPU 线程的十进制 tid
- 将 tid 转为十六进制(如 12345 → 0x3039),在 jstack 输出中搜索 nid=0x3039
- 找到对应线程后,看其 stack trace:是否在死循环?是否在密集正则匹配?是否在频繁 GC?是否卡在 synchronized 方法或锁竞争?
- 特别注意 RUNNABLE 状态但长期不退出的方法调用(如 String.replaceAll、HashMap.get 在极端 hash 冲突下)

















