jstack和VisualVM是JDK自带的死锁排查主力工具:jstack命令行轻量高效,适合生产环境快速定位;VisualVM图形化直观,适合本地调试与深度分析,二者互补使用效果最佳。

Java 死锁排查不靠猜,靠工具抓现场。jstack 和 VisualVM 是 JDK 自带的两个主力工具,一个命令行快准狠,一个图形化直观易读,配合使用效率最高。
jstack 快速定位死锁线程
它是最轻量、最直接的方式,适合生产环境快速诊断。
- 先用 jps -l 或 ps aux | grep java 找到目标 Java 进程 PID
- 执行 jstack -l
> thread_dump.txt —— -l 参数必须加,否则看不到锁对象地址和持有关系 - 打开输出文件,直接搜索 “Found one Java-level deadlock”,jstack 会自动检测并汇总死锁段落,明确列出哪些线程在互相等待哪把锁
- 若没看到自动报告,就重点查 BLOCKED 状态线程,结合 waiting to lock 和 locked 两行,比对锁地址是否成环
- 别在终端直接运行 jstack,堆栈太长容易刷屏;重定向后可用 grep -A 5 -B 3 "BLOCKED\|waiting to lock" 快速过滤关键上下文
VisualVM 图形化识别死锁
适合本地调试或远程连接开发/测试环境,能实时观察线程状态变化。
- 启动 jvisualvm(JDK 自带,无需额外安装)
- 左侧进程列表选中目标应用,切换到 “线程” 标签页
- 点击右上角 “线程 Dump” 按钮获取当前快照;死锁线程会被标为 红色,并显示 “Deadlock detected” 提示
- 展开死锁线程,可直接看到完整堆栈、锁对象类名及等待/持有关系,比纯文本更易关联代码位置
- 如需远程监控,JVM 启动时必须加上完整 JMX 参数:-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=实际IP
对比与使用建议
两者不是二选一,而是互补:
立即学习“Java免费学习笔记(深入)”;
- jstack 更适合线上紧急排查:无界面依赖、脚本友好、资源占用低,10 秒内完成 dump + 分析
- VisualVM 更适合深度分析:支持线程状态趋势图、CPU 占用热力、内存联动查看,方便复现和验证修复效果
- 遇到疑似死锁但 jstack 未报出,要检查是否是 活锁(RUNNABLE 状态持续高 CPU)或锁竞争严重导致的假性卡顿,这时 VisualVM 的实时线程视图更有价值
- 日常开发可在单元测试后跑一次 jstack -l,配合代码审查锁顺序,提前拦截典型双锁反序问题


















