
https://arthas.aliyun.com/doc/
我们来系统性地梳理和掌握 Java 问题诊断工具集。这些工具是每个 Java 开发者(尤其是后端开发者)必须掌握的“手术刀”,用于快速定位线上故障、性能瓶颈和内存问题。
这些工具主要分为两类:
-
JDK 自带命令行工具 (
jps,jstat,jstack,jmap,jinfo) -
图形化/高级诊断工具 (
JConsole,VisualVM,Arthas,MAT)
一、JDK 自带命令行工具
这些工具位于 JAVA_HOME/bin/ 目录下,是诊断的“第一响应”工具,尤其在无图形界面的服务器环境中至关重要。
1. jps (JVM Process Status Tool)
-
作用:列出当前用户的所有 Java 进程及其主类名和 PID(进程ID)。类似于
ps -ef | grep java,但更简洁直接。 -
常用命令:
bash
jps -l # 显示完整的主类名或jar包名 jps -v # 显示启动时传递给JVM的参数 jps -mlv # 上述所有信息的组合 -
使用场景:快速找到你要诊断的 Java 应用的 PID。
2. jstat (JVM Statistics Monitoring Tool)
-
作用:监控 JVM 的各种运行时状态信息,主要是堆内存和垃圾回收情况。这是监控 GC 问题最核心的命令行工具。
-
常用命令:
bash
jstat -gc <pid> 1s 10 # 每1秒采样一次,共10次,输出GC相关信息 jstat -gccapacity <pid> # 监控各个代的容量和使用情况 jstat -gcutil <pid> 1s # 以百分比形式显示GC总体情况(最常用) -
关键指标解读(看
-gcutil输出):-
S0,S1,E: Survivor0/1 和 Eden 区的使用百分比。 -
O: Old 区使用百分比。如果长时间接近100%,则可能内存泄漏或堆大小不足。 -
M: Metaspace 使用百分比。 -
YGC,YGCT: Young GC 的次数和总耗时。 -
FGC,FGCT: Full GC 的次数和总耗时。这是最重要的指标!如果 FGC 频繁且 FGCT 很长,说明系统正在“卡死”。
-
3. jstack (Stack Trace Tool)
-
作用:生成 JVM 当前时刻的线程快照。用于定位线程出现长时间停顿的原因,如死锁、死循环、请求外部资源耗时过长等。
-
常用命令:
bash
jstack <pid> # 打印线程栈信息 jstack -l <pid> # 除了堆栈外,还显示关于锁的附加信息(用于分析死锁) -
使用场景:
-
CPU 占用过高:先用
top -Hp <pid>找到占用 CPU 最高的线程 ID,将其转换为 16 进制(printf "%x\n" <nid>),然后在jstack的输出中查找这个nid,看哪个线程正在执行什么代码。 -
应用无响应/死锁:直接运行
jstack -l <pid>,输出结果最下面会明确提示是否发现死锁。
-
4. jmap (Memory Map Tool)
-
作用:生成堆内存转储快照(Heap Dump) 或查看堆内对象的统计信息。
-
【警告】:
jmap -dump会触发 Full GC,并且会暂停应用,严禁在线上系统随意使用! -
常用命令:
bash
jmap -heap <pid> # 显示堆的摘要信息(GC算法、堆配置、各代状态) jmap -histo:live <pid> # 显示堆中对象的统计信息,包括类名、实例数量、合计容量 jmap -histo:live <pid> | head -20 # 只看前20行,快速找出哪些对象最多 jmap -dump:format=b,file=heap.hprof <pid> # 生成堆转储文件(用于MAT分析) -
使用场景:
-
-histo:快速怀疑是否有内存泄漏。如果某个类的对象数量异常多,就很可疑。 -
-dump:在发现内存泄漏迹象或出现OutOfMemoryError后,保留现场,生成 dump 文件供后续使用 MAT 等工具进行深度分析。
-
5. jinfo (Configuration Info Tool)
-
作用:实时查看和调整虚拟机参数。
-
常用命令:
bash
jinfo <pid> # 显示所有JVM参数和系统属性 jinfo -flags <pid> # 显示显式设置的JVM参数 jinfo -sysprops <pid> # 显示系统属性 jinfo -flag <name> <pid> # 查看某个特定参数的值 jinfo -flag [+|-]<name> <pid> # 开启或关闭某个BOOL型参数(如PrintGC) jinfo -flag <name>=<value> <pid> # 动态修改某个参数的值(非所有参数都支持) -
使用场景:确认某个参数是否生效,或者在紧急情况下动态开启 GC 日志等。
二、图形化/高级诊断工具
1. JConsole & VisualVM
-
JConsole:JDK 自带的简单监控工具。可以监控堆内存、线程、类、CPU 消耗等信息,支持连接本地和远程进程。
-
VisualVM:功能更强大的免费工具,集成了 JConsole 的功能,并提供了更丰富的插件(如 Visual GC,可以可视化地看到堆内存各区域的变化)。
-
使用场景:在开发、测试或预发环境进行实时可视化监控,比命令行更直观。
2. Arthas (阿尔萨斯) - 必须非常熟练
-
简介:阿里巴巴开源的Java诊断神器,基于命令行交互,功能极其强大,彻底解决了线上调试的痛点。
-
核心特性:
-
无需修改代码、无需重启应用即可动态跟踪诊断。
-
内置了大量强大的命令,解决了
jstack,jmap,jinfo等工具需要多步操作的麻烦。
-
-
必须掌握的核心命令:
-
dashboard:实时仪表盘,一眼看清线程、内存、GC、运行环境信息。 -
thread <id>/thread -n 3:查看指定线程栈 / 找出最忙的3个线程。完美替代jstack找 CPU 高的线程。 -
jad com.example.MyClass:反编译指定类,查看线上运行的代码是否是最新的。 -
watch com.example.Service login '{params, throwExp}':观测方法调用的入参、返回值、异常。这是神器级功能,用于debug。 -
trace com.example.Service login:追踪方法内部调用路径,并输出每个节点的耗时。定位性能瓶颈的终极武器。 -
heapdump /path/to/file.hprof:生成堆转储文件(类似于jmap -dump,但更安全方便)。 -
ognl @com.example@getBean():执行ognl表达式,动态获取Spring容器中的Bean。用于验证配置是否生效。
-
-
使用场景:几乎所有的线上问题诊断,特别是需要“窥探”应用内部运行状态而又不能重启时。
3. MAT (Eclipse Memory Analyzer Tool)
-
作用:用于深度分析
jmap或Arthas生成的堆转储文件(heap dump),定位内存泄漏的根因。 -
核心功能:
-
Leak Suspects Report(泄漏嫌疑报告):MAT 会自动分析并给出可能发生内存泄漏的疑点。
-
Histogram(直方图):查看类的实例数量和占用的内存大小。找出疑似泄漏的类。
-
Dominator Tree(支配树):列出堆中最大的对象,以及谁持有这些对象的引用。这是找到“谁阻止了GC回收这些对象”的关键。
-
Path to GC Roots(到GC根的路径):找到某个对象为什么不被回收的完整引用链。这是最终确认内存泄漏的铁证。
-
-
使用场景:当发现老年代使用率持续走高、Full GC 频繁时,dump 出堆文件,用 MAT 加载分析,找到无法被回收的对象及其引用路径。
三、实战问题排查流程
-
CPU 飙升:
-
top-> 找到 Java 进程 PID 和占用高的线程 ID。 -
printf "%x\n" <tid>-> 将线程 ID 转为十六进制nid。 -
jstack <pid>-> 在输出中查找nid,定位到代码行。或者直接用arthas的thread命令。
-
-
应用卡顿、响应慢:
-
jstat -gcutil <pid> 1s-> 观察 FGC 次数和耗时,如果频繁且长,是 GC 问题。 -
jstack -l <pid>-> 检查是否有死锁(输出最下方会提示)。 -
用
arthas的trace命令追踪可疑方法的耗时。
-
-
内存泄漏 OOM:
-
jmap -histo:live <pid> | head -20-> 初步怀疑哪个对象过多。 -
使用
arthas的heapdump或jmap -dump抓取堆快照。 -
用 MAT 工具加载
.hprof文件,分析 Dominator Tree 和 Path to GC Roots,找到泄漏对象和持有它的引用链。
-
总结:命令行工具是基础,Arthas 是日常诊断的瑞士军刀,MAT 是解决复杂内存问题的终极法宝。熟练运用这套工具集,你就能从容应对绝大多数 Java 线上问题。
1842

被折叠的 条评论
为什么被折叠?



