☰
Arthas 实战:线上诊断的“瑞士军刀“(工具篇)
2026/10/6 9:25:09 网站建设 项目流程

Arthas 实战:线上诊断的"瑞士军刀"(工具篇)

环境:CentOS 7 / JDK 17 / Arthas 4.3.3
定位:前面 8 篇是"手工排查练内功",本篇是"工具提效"——同一批病例,换 Arthas 再诊断一遍
系列:CPU 100% / 锁竞争 / 频繁 Young GC / 切换风暴 / 下游慢 / 池耗尽 / 死锁 / OOM
关键词:attach、thread -n、thread -b、jad、watch、ognl、heapdump

一、Arthas 是什么?为什么生产敢用?

阿里开源的 Java 诊断工具,核心能力:不重启、不改代码,attach 到运行中的 JVM 上做诊断。

生产敢用的三个理由:

  1. attach 机制:通过 JVMTI 把 agent 挂进目标 JVM(和 jstack/jmap 同一套机制),不需要重启服务
  2. 字节码增强可还原:watch/trace是临时增强目标方法的字节码,reset一键还原类
  3. 只读为主:绝大多数命令只观测不修改(ognl 例外,能调方法,慎用)

注意:dashboard 里能看到arthas-NettyHttpTelnetBootstrap等线程——Arthas attach 后是"住进"目标 JVM 的,它的线程也会出现在诊断结果里(观察者效应)。

二、上手:下载、attach、退出

wgethttps://arthas.aliyun.com/arthas-boot.jarjava-jararthas-boot.jar# 列出 Java 进程,输入【序号】(不是 PID!)
操作命令效果
断开但 agent 留在 JVMquit/exit下次 attach 更快,但 agent 常驻
完全卸载 agentstop不留痕迹,生产用完推荐

纪律:必须用和目标进程相同的用户启动 arthas-boot,JDK 大版本别太老。

三、手工 vs Arthas 对照表(本篇灵魂)

手工流程(前 8 篇)Arthas场景
top -H→printf %x→jstack grep nidthread -n 3一条搞定A1 CPU 高
jstack状态统计找 BLOCKED → grep 锁地址 → 找持锁者thread -b自动揪持锁者B1 锁竞争
jstack | grep State | sort | uniq -cthread --state BLOCKED(标题行直接印统计)状态分布
jstat -gc 1000 10两次采样算差值dashboard实时面板A2 GC
jmap -histo/jmap -dumpmemory/heapdumpB4 内存
翻 jar 包确认代码版本jad反编译线上类版本核对
加日志→发版→复现watch/trace免日志观测方法级排查

四、实战命令详解(全部真实演练)

① dashboard——综合面板(替代 top+jstat+jstack 三窗口)

  • 线程区:main线程 RUNNABLE 99.75% 直接登顶(不用转 16 进制)
  • Memory 区:heap/eden/old_gen/metaspace 实时水位 + GC 次数耗时
  • Runtime 区:load、核数、JVM 版本

② thread -n 3——CPU 排查一条命令

"main" Id=1 cpuUsage=100.0% deltaTime=200ms time=873782ms RUNNABLE at com.jvm.cpu.CpuHighDemo$DeadLoop.main(CpuHighDemo.java:32)

  • cpuUsage + deltaTime:采样窗口内的瞬时占用
  • time:累计 CPU 时间(等价 jstack 的cpu=)
  • 直接打印完整堆栈,栈顶就是那行死循环

③ thread -b——锁竞争的"自动破案"

推荐动线:先 dashboard 定方向,再 thread -b 抓凶手。

第一步,dashboard线程区一眼定调——STATE 列一片红色BLOCKED,且每个 Worker 的 %CPU 都接近 0:

读图要点:状态红 + CPU 低 = 没人干活全在排队(等锁/等池子系)。如果是 A1 死循环,这里应该是某个线程绿色 RUNNABLE + 99% CPU。一个 dashboard 就把"干活系"和"等待系"分开了。

第二步,thread -b精准定位持锁者:

"Worker-15" Id=28 TIMED_WAITING at java.lang.Thread.sleep(Native Method) at ...LockContention.lambda$main$0(CpuHighDemo.java:122) - locked java.lang.Object@243ef36b <---- but blocks 18 other threads!

持锁者 + 锁地址 + 受害规模,三合一输出——手工时代这是半篇博客的排查量。

④ jad——反编译线上代码(发错包的克星)

jad com.jvm.cpu.CpuHighDemo$LockContention

输出头部两行隐藏情报:

ClassLoader: +-AppClassLoader ... ← 谁加载的(类冲突/元空间问题用) Location: /home/lhadmin/jvm-demo/target/classes/ ← 从哪个物理路径加载的

面试题"怎么确认线上代码版本"的标准答案:jad反编译正在运行的类,和源码对照。

⑤ watch——免日志观测方法(布控式)

watch com.jvm.cpu.CpuHighDemo$LockContention lambda$main$0 '{params,returnObj}' -x 2 -n 3 # Affect(class count: 1, method count: 1) cost in 110 ms, listenerId: 1
  • {params,returnObj,throwExp}:观测入参/返回值/异常,-x 2展开深度,-n 3抓 3 次自动停
  • 配套:trace(方法内调用链逐跳耗时,定位慢在哪一行)、monitor -c 5(方法调用统计)、stack(谁调用了这个方法)
  • 用完reset还原被增强的类

⑥ ognl——直接读写运行时对象

ognl '@com.jvm.cpu.CpuHighDemo$LockContention@counter.get()' # @Integer[625634] ← 静态变量实时值

踩坑实录(JDK 9+ 模块墙):

ognl '@...@counter' # 直接读对象 → 报错: InaccessibleObjectException: module java.base does not "opens java.util.concurrent.atomic"

OGNL 默认反射序列化整个对象(含私有字段),JDK 9+ 模块化拦下。解法:不读字段,改调 public 方法.get()——这也是生产环境--add-opens参数存在的意义。

⑦ heapdump——一条命令导堆(但生产纪律不变)

heapdump /tmp/arthas-dump.hprof # Heap dump file created

两个必须说清的点:

  1. 它只是"导出变简单了":Arthas 的 heapdump 本质就是jmap -dump换皮(底层同一个 HotSpot dumpHeap 调用),同样 STW、文件同样≈堆大小——别以为换了工具就没代价了。生产环境依然要遵守第 8 篇的纪律:低峰期或摘流量后再导;只想粗判先用memory(等价 jmap -histo,不触发 FGC)
  2. 分析还是 MAT/VisualVM 的活:heapdump 只负责把堆"搬出来",支配树、Leak Suspects、引用链分析仍在 MAT/VisualVM 里做,完整流程见第 8 篇

一句话:Arthas 优化的是"怎么拿出来",不是"要不要 STW",更不替代"怎么分析"。

五、其他高频命令速查

命令干什么面试场景
jvmJVM 整体信息快速摸底
vmoption查看/动态改 JVM 参数"线上能临时开 GC 日志吗"→ 能
logger动态改日志级别不重启开 DEBUG
getstatic 类名 字段名看静态字段(ognl 的简便版)读配置开关
profiler start/stopasync-profiler 火焰图CPU/内存分配热点,性能分析压轴
sc -d 类名类的加载信息类冲突排查
tt -t 类 方法记录方法调用时空隧道,可回放疑难偶发问题

六、面试 60 秒话术

“线上诊断我用 Arthas,它通过 attach 机制挂进 JVM,不用重启。CPU 高用thread -n直接拿热点线程堆栈,锁问题thread -b自动找持锁者;确认代码版本用jad反编译;方法级排查用watch/trace免日志观测入参返回值和逐跳耗时;运行时的静态值用ognl读;堆问题heapdump导出来 MAT 分析。增强类用完reset还原,退出用stop卸载 agent 不留痕迹。手工的 top/jstack/jstat 命令链我也熟——那是理解原理,Arthas 是生产提效。”

口诀:热点 -n、找锁 -b、版本 jad、观测 watch、读值 ognl、导堆 heapdump;attach 来、stop 走,reset 还原不留痕。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询