Skip to content

dashboard/thread/heapdump 命令

Arthas 核心命令详解

上一节介绍了 Arthas 的安装和基础指令,这一节深入讲解三个最常用的核心命令:dashboard、thread 和 heapdump。

dashboard:系统实时仪表盘

详解 dashboard 的输出

dashboard 每秒刷新一次,提供 JVM 运行的全景视图:

┌──────────────────────────────────────────────────────────────────┐
│  Java Process Information                                       │
│    PID: 12345 | Process Start Time: 2026-03-22 08:00:00         │
│    Uptime: 2h 30m | Total Started Threads: 45 | Daemon: 38     │
├──────────────────────────────────────────────────────────────────┤
│  Thread Panel                                                    │
│  Name                                TID    STATE    CPU%  TIME  │
│  http-nio-8080-exec-1               0x123  WAITING   5.2  1.2s  │
│  http-nio-8080-exec-2               0x124  RUNNABLE  3.1  0.8s  │
│  pool-1-thread-1                   0x200  TIMED_WT  0.1  0.2s  │
├──────────────────────────────────────────────────────────────────┤
│  Memory Panel (MB)                                              │
│  Heap: 1024/2048 used (50%)                                    │
│  Eden:  256/512 used (50%)                                     │
│  Old:   512/1024 used (50%)                                     │
│  Metaspace: 128/256 used (50%)                                  │
├──────────────────────────────────────────────────────────────────┤
│  GC Panel                                                        │
│  G1 GC: 12 times | Total Cost: 1.23s                           │
│  Young GC: 10 times | 0.23s                                     │
│  Full GC: 2 times | 1.00s                                       │
├──────────────────────────────────────────────────────────────────┤
│  Runtime                                                        │
│  os.name: Linux | os.version: 5.4.0                            │
│  java.version: 17.0.2 | java.home: /usr/lib/jvm/java-17        │
└──────────────────────────────────────────────────────────────────┘

按条件过滤 dashboard

bash
# 过滤特定包名的线程
dashboard -t com.example

# 按线程状态过滤
# RUNNABLE / BLOCKED / WAITING / TIMED_WAITING

与 top 的区别

dashboard vs top:
top      → 系统层面,CPU 包含 GC 线程
dashboard → JVM 层面,排除 GC 线程的纯应用 CPU

dashboard 排除了 GC 线程,能更准确地反映应用程序本身的 CPU 消耗。

thread:线程分析

查看所有线程

bash
thread

# 输出:
# Threads Summary
#   Id   Name                       CPU%   STATE     TIME   INTERRUPTED  DAEMON
#    1   main                       0.0%   RUNNABLE  0.012s   false        false
#   12   Reference Handler           0.0%   WAITING   0.001s   false        true
#   13   Finalizer                  0.0%   WAITING   0.001s   false        true
#   14   Signal Dispatcher           0.0%   RUNNABLE  0.000s   false        true
#   23   http-nio-8080-exec-1       5.2%   WAITING   1.234s   false        true
#   24   http-nio-8080-exec-2       3.1%   RUNNABLE  0.876s   false        true
#   25   pool-1-thread-1            0.1%   TIMED_WAIT 0.543s  false        true

查看最忙的线程

bash
# 查看最忙的 5 个线程
thread -n 5

# 输出:
# Most busy Java threads
#   Id   Name                       CPU%   TIME   STATE
#   23   pool-1-thread-1            35.2%  5.234s RUNNABLE
#     at java.lang.Object.hashCode(Native Method)
#     at java.util.HashMap.hash(HashMap.java:456)
#     ...
#   24   pool-1-thread-2            12.3%  2.345s RUNNABLE
#     at com.example.Service.process(Service.java:78)
#     ...

查看阻塞的线程

bash
# 查看正在等待锁的线程
thread -b

# 输出:
#  Blocked threads (阻塞中)
#   Id   Name                       TIME   BLOCKED_TIME  LOCK
#   25   pool-1-thread-3            1.234s  1234ms      @0x7f8a12345678
#     waiting for monitor entry to 0x7f8a12345678
#     held by: pool-1-thread-1 (@0x7f8a12345670)

死锁检测

bash
# 检测死锁
thread -b

# 如果发现死锁,输出:
# Found dead lock:
# ===
# "Thread-A" id=24
#   waiting for锁 @0x7f8a00000000
#   held by "Thread-B" id=25
# "Thread-B" id=25
#   waiting for锁 @0x7f8a00000010
#   held by "Thread-A" id=24

查看指定线程详情

bash
# 查看线程 ID 为 23 的详细堆栈
thread 23

# 输出:
# "pool-1-thread-1" Id=23 cpu=35.2% RUNNABLE
#     at java.lang.Object.hashCode(Native Method)
#     at java.util.HashMap.hash(HashMap.java:456)
#     at java.util.HashMap.get(HashMap.java:317)
#     at com.example.Cache.get(Cache.java:45)
#     at com.example.Service.process(Service.java:78)
#     ...

线程状态分析

线程状态解释:

RUNNABLE    → 正在运行或等待 CPU(注意:等待 CPU 的线程也显示 RUNNABLE)
BLOCKED     → 等待获取监视器锁
WAITING     → 无限期等待(wait/join/park)
TIMED_WAITING → 有限期等待(sleep/join with timeout/sleep)
NEW         → 未启动
TERMINATED  → 已结束

实际案例:定位 CPU 飙升

bash
# 1. 查看最忙的线程
thread -n 3 --use-regexp

# 2. 查看具体堆栈
thread 23

# 3. 结合 jstack 输出到文件
jstack 12345 > thread_dump.txt

# 4. 分析热点
# - 如果是业务代码:优化算法或增加缓存
# - 如果是 hashCode/native 方法:检查 HashMap 使用
# - 如果是 GC:调优 GC 参数

heapdump:堆转储

生成堆转储

bash
# 生成堆转储到临时文件
heapdump

# 生成到指定文件
heapdump --live /tmp/heapdump.hprof

# --live 参数:只转储存活对象(推荐,先触发 GC)
# 不加 --live:转储整个堆

heapdump 与 jmap 的区别

heapdump vs jmap:
heapdump(Arthas):
  ✓ 不需要指定文件路径(自动生成)
  ✓ 可以指定 --live 只转储存活对象
  ✓ 可以在 dashboard 界面中触发

jmap(JDK):
  ✓ 更底层,直接调用 JVM 接口
  ✓ -hprof 参数更灵活
  ✓ 适合脚本自动化

使用 MAT 分析堆转储

bash
# 1. Arthas 中生成
heapdump --live /tmp/live_heap.hprof

# 2. 下载到本地
scp user@server:/tmp/live_heap.hprof /tmp/

# 3. 用 MAT 打开分析
# MemoryAnalyzer -hprofPath /tmp/live_heap.hprof

heapdump 的使用场景

bash
# 场景一:排查内存泄漏
heapdump --live /tmp/heap_$(date +%Y%m%d_%H%M%S).hprof

# 场景二:OOM 时自动生成
# 在应用启动参数中加入:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/

# 场景三:对比两个时间点的堆
heapdump --live /tmp/heap_before.hprof
# 执行大量操作
heapdump --live /tmp/heap_after.hprof
# 用 MAT 对比两个堆的变化

命令组合使用

场景:应用响应变慢的综合诊断

bash
# 1. 查看整体状态
dashboard

# 2. 查看线程情况
thread -n 5

# 3. 查看是否有死锁
thread -b

# 4. 找到最耗 CPU 的线程
thread 23
# 如果确定是热点,保存堆栈
jstack > /tmp/thread_dump.txt

# 5. 生成堆转储
heapdump --live /tmp/heap.hprof

# 6. 继续监控
monitor -c 60 com.example.Service process
trace com.example.Service process '#cost > 10'

场景:内存持续增长

bash
# 1. 持续观察内存
dashboard
# 关注 Heap Used 和 Old Gen 的变化趋势

# 2. 多次触发堆转储对比
heapdump --live /tmp/heap_1.hprof
# 运行一段时间
heapdump --live /tmp/heap_2.hprof

# 3. 用 MAT 对比
# File → Compare → 选择两个堆文件
# 观察哪些对象在增长

# 4. 结合 Arthas 观察对象创建
watch com.example.Cache put '{params, returnObj}' -x 3

常用快捷操作

Arthas 常用操作:
1. Ctrl+C → 退出当前命令
2. Ctrl+Z → 挂起命令
3. jobs → 查看后台任务
4. job <id> → 切换到指定任务
5. quit → 退出 Arthas 连接
6. stop → 停止 Arthas Agent
7. reset → 重置所有增强的方法

本节小结

dashboard/thread/heapdump 核心要点:

维度dashboardthreadheapdump
作用系统全景监控线程分析堆内存转储
刷新每秒自动刷新一次性输出按需生成
关键参数-t 过滤线程-n 最忙线程,-b 阻塞--live 存活对象
诊断场景实时观察系统状态线程阻塞、CPU 热点、死锁内存泄漏、OOM

三剑客配合使用:dashboard 实时观察 → thread 定位线程问题 → heapdump 生成堆转储深入分析。

下一节,我们来看 sc/sm/jad/monitor/watch 命令

基于 VitePress 构建