async-profiler、Arthas、jstack 到底什么时候该先用哪个?
线上排障时,async-profiler、Arthas、jstack 经常一起出现,但它们拿到的不是同一种证据。`jstack` 给你线程当下停在哪,Arthas 适合在线核对方法、参数和调用来源,async-profiler 则用一段时间的采样告诉你热点是不是稳定存在。
线上 Java 排障时,很多团队都会同时提到这几样工具:
jstack- Arthas
- async-profiler
名字都熟,真正麻烦的是现场问的问题经常不止一个。
同一次故障里,你可能会连续碰到这些犹豫:
- CPU 高时,先抓
jstack,还是直接上 async-profiler - 接口慢时,是先用 Arthas
trace,还是先看线程栈 - 已经拿到一些输出了,但还说不清自己缺的是瞬时快照、方法级验证,还是累计热点
于是现场很容易演变成:
- 抓了几份线程栈
- 开了 Arthas 看方法
- 又补一轮 profiler
- 三类证据都沾了一点,但没有哪一类真正坐实
这篇主要想把一个核心问题讲清:
现在这个症状,更缺哪一种证据?该拿
jstack、Arthas,还是 async-profiler?
先记这三句话:
jstack:看线程这一刻卡在哪、等什么、跑什么- Arthas:在线核对方法、参数、调用来源和代码实现
- async-profiler:看几十秒到几分钟里,CPU 或分配热点到底稳定落在哪
把这三句话记住,现场至少不会因为“工具都懂一点”而把证据打散。
三把工具各自负责哪类证据
还在犹豫用哪把工具时,可以拿手头问题对一下这张表。
| 你现在卡在哪里 | 先看哪里 | 为什么 |
|---|---|---|
你知道现场要上工具,但不确定先用 jstack、Arthas 还是 async-profiler | 先把这篇看完 | 先把三把工具的边界立住,再动手 |
| 已经确定用 Arthas,只想补最常用命令顺序 | Arthas 在线上排障时,最值得先掌握的 6 个命令怎么用? | 直接看命令和现场用法 |
| 已经确定先看 JVM 原生工具边界 | 线上问题排查时,jstack、jmap、jstat 分别怎么看 | 直接看原生工具怎么配合 |
| 现场核心是 CPU 高,需要线程、GC、热点一并判断 | Java CPU 飙高怎么排查:一套线上定位顺序 | 先沿 CPU 主线收证据 |
| CPU 与 GC 因果纠缠在一起,想先立证据顺序 | CPU 高和 GC 抖同时出现时,先证明谁是因谁是果? | 先把谁先谁后分清 |
先把三把工具的边界立住
你已经知道要进 JVM 里取证,但还没想清楚自己缺的是线程快照、在线验证,还是一段时间内的热点画像。
如果已经确定要用某一把工具,直接去对应实战页更快。本文不展开 CPU、GC、线程池、OOM 这些故障主线。
这里主要做一件事:把三类证据和三把工具的边界分清,避免一上来把 jstack、Arthas、async-profiler 全打一遍。
一、三种工具对应三种证据
它们都会接触 JVM,但回答的问题层次并不一样。
jstack 更像什么
更像:
- 一张线程现场快照
- 适合回答线程此刻在跑什么、等什么、卡什么
Arthas 更像什么
更像:
- 一个在线交互式诊断入口
- 适合回答某个方法慢在哪、参数是什么、调用来源是什么、线上跑的是哪份代码
async-profiler 更像什么
更像:
- 一段时间内的采样画像
- 适合回答 CPU、分配热点真正长期集中在哪,而不是某个瞬间刚好停在哪
这三者最容易被混淆的地方就在于:
- 它们都能碰到“性能问题”
- 但证据形态完全不一样
所以第一原则是:
先想清楚你现在缺的是“瞬时线程现场”“交互式验证”还是“持续采样画像”。
二、什么时候优先用 jstack
如果你怀疑问题更偏:
- 线程阻塞
- 死锁
- 某个线程池卡住
- 高 CPU 线程当前到底在跑什么
- 大量线程在等数据库、等锁、等下游
那通常更适合先出手的是 jstack。
它最擅长回答的问题
- 哪些线程现在最值得看
- 当前线程停在什么调用栈
- 大量线程是否卡在同一个等待点
- 有没有明显死锁或锁等待链
常见使用方式
jstack <pid>
更实战一点的习惯通常是连续抓几次:
jstack <pid> > /tmp/jstack-1.log
sleep 3
jstack <pid> > /tmp/jstack-2.log
sleep 3
jstack <pid> > /tmp/jstack-3.log
它最值钱的场景
- CPU 高时先找热点线程栈
- 服务卡住时先分线程是在跑、在等还是在锁上
- 线程池堆积时先看工作线程都堵在哪里
它的边界
jstack 很擅长回答“此刻线程在干什么”,但不擅长单独回答:
- 哪段代码在一段时间里累计最吃 CPU
- 某个热点方法内部耗时比例如何
- 某个参数组合是不是正在触发坏路径
也就是说,它适合“线程快照”,不适合独立做长期热点画像。
三、什么时候优先用 Arthas
如果你已经有了一点怀疑方向,想在线验证更细的问题,Arthas 往往更合适。
例如你想回答:
- 某个方法到底慢在哪一层
- 某个方法实际收到的参数是什么
- 某条调用链是谁调进来的
- 线上跑的类和你以为的是不是同一份代码
它最擅长回答的问题
- 某个方法耗时拆分
- 参数、返回值、异常是否符合预期
- 调用来源是什么
- 线程和 JVM 运行态整体有没有异常
常见场景
- 接口慢,但你已经知道大概是哪层 service 或 client 可疑
- 某类请求参数怀疑触发了坏路径
- 想确认线上代码实现和本地认知是否一致
- 需要快速看线程、方法、参数,不想在多个工具之间切换
常见命令方向
dashboardthreadtracewatchstackjad
如果你想看具体怎么串,站内已经有一篇更完整的拆解:
它的边界
Arthas 很强,但不要把它理解成“万能替代一切”。
它不天然替代:
- 系统层工具
- 持续采样型 profiler
- 全量时间序列监控
它更适合:
你已经有怀疑点,想在现场更快验证。
四、什么时候优先用 async-profiler
如果你面对的是:
- CPU 高,但单次线程栈总感觉不够稳
- 怀疑热点不在一个瞬时栈,而是在一段时间里稳定出现
- 想看分配热点、锁竞争、火焰图
- 想证明真正长期消耗集中在哪,而不是某一刻恰好停在哪
这时 async-profiler 往往比只抓几次 jstack 更有价值。
它最擅长回答的问题
- 一段时间里 CPU 热点真正集中在哪些方法
- 哪些路径累计最吃资源
- 哪些对象分配路径最重
- 热点到底是 Java 栈、native 栈,还是混合路径
为什么它在线上很值钱
因为很多问题是动态的。
例如:
- 某线程栈在不同瞬间位置会跳
- 单次
jstack只能说明这一刻 - 但真正的热点是“这一分钟里反复出现最多的那条路径”
async-profiler 更擅长回答这种“累计热点”问题。
它最合适的场景
- Java CPU 高,但
jstack多次抓栈仍然不够稳定 - 想看序列化、加解密、对象转换、日志、JSON 这些热点到底谁更重
- 想证明某个热点是持续的,不是偶然快照
它的边界
async-profiler 强在采样画像,但不直接回答:
- 某个方法的参数到底是什么
- 线上这份类代码和你预期是否一致
- 某条调用到底是谁调进来的
所以它很强,但也不是 Arthas 的替代品。
五、一个最实用的理解:三者分别对应三种证据
如果只记一句最实用的话,可以记这个:
jstack:线程快照证据- Arthas:交互验证证据
- async-profiler:持续采样证据
为什么这个理解最重要
因为线上排障最怕的不是工具不会,而是证据形态混乱。
例如:
- 你缺的是长期热点画像,却一直抓瞬时线程栈
- 你缺的是参数和调用来源,却一直开 profiler
- 你缺的是线程阻塞点,却先去 trace 很宽的方法范围
只要先分清证据类型,工具选择会自然很多。
六、不同现场下,通常更适合先用哪个
下面这几组不是固定流程,更像是我在现场里常用的起手区别:先拿到最缺的那类证据,再决定要不要补第二把工具。
场景 1:CPU 高,先想知道线程现在在干什么
更贴近现场的顺序通常是:
top -Hp/pidstat -tjstack- 如果线程栈不够稳定,再补 async-profiler
为什么这样更稳:
- 先用线程栈知道“此刻谁在忙”
- 再用 profiler 证明“长期到底谁最热”
场景 2:接口慢,已经大概知道可疑方法
更贴近现场的顺序通常是:
- Arthas
dashboard/thread - Arthas
trace - 必要时
watch/stack
为什么:
- 你缺的是方法级验证,不是先做全局采样画像
场景 3:线程池堆积、服务卡住,想知道在等什么
更贴近现场的顺序通常是:
jstack- Arthas
thread - 再结合数据库、连接池、下游监控
为什么:
- 这类问题首先要回答的是等待点,而不是长期 CPU 热点
场景 4:CPU 高、对象创建多,怀疑分配热点
更贴近现场的顺序通常是:
- 先用
jstack或 Arthasthread建立方向感 - 再用 async-profiler 看 CPU / alloc 画像
- 回到热点代码做验证
为什么:
- 这时单靠瞬时栈很容易不够,采样画像价值会更高
场景 5:怀疑线上代码、参数或调用来源不对
更贴近现场的顺序通常是:
- Arthas
watch - Arthas
stack - Arthas
jad
因为这类问题:
jstack不擅长- profiler 也不擅长
- Arthas 正好最顺手
七、一个更实用的总顺序:先轻量定方向,再选深入工具
很多现场其实不需要一上来就把三个工具都打开。
我更推荐这个主线:
第 1 步:先确定问题更像哪一类
- 线程等待 / 死锁 / 卡住
- 方法慢 / 参数错 / 调用来源不清
- 长期 CPU / 分配热点
第 2 步:选第一把最合适的工具
- 线程现场优先
jstack - 交互验证优先 Arthas
- 长期热点画像优先 async-profiler
第 3 步:只在证据不足时补第二把工具
例如:
jstack不够稳,再补 profiler- 线程知道卡在哪了,再补 Arthas 验证参数或慢层级
- profiler 看到热点,再回到 Arthas 或代码验证
这样做的好处是:
- 不会一上来把现场搞得很吵
- 不会把不同类型证据混在一起
- 更容易形成清晰排查链
八、关键误判
误判 1:CPU 高就应该直接上 profiler
不一定。
很多时候先看线程现场更快,至少先分清是线程等待、GC 线程,还是业务线程热点。
误判 2:会 Arthas 就不用 jstack 了
不对。
jstack 仍然是线程快照和死锁、等待链判断里的基础工具。
误判 3:抓了几次 jstack 就能替代 profiler
也不一定。
如果热点是动态漂移的,持续采样画像会更稳。
误判 4:Arthas 越强,就越应该什么都用它来做
错。
Arthas 更适合交互验证,不代表它自动替代所有采样和系统层排查。
九、FAQ:现场最容易混在一起的几个问题
1. 如果我只会一个,先学哪个?
如果你还在补最基础的线上判断,先把 jstack 用熟。
它不一定覆盖最广,但能逼着你先看线程状态、等待点和调用栈,这些判断在很多故障里都躲不过去。
2. CPU 高时,jstack 和 async-profiler 谁更优先?
先看你要回答哪个问题。
如果你先想知道“高 CPU 线程此刻在跑什么”,先抓 jstack;如果你已经发现线程栈位置漂移很大,想确认几十秒内真正反复出现的热点,再补 async-profiler。
3. Arthas 最大的独特价值是什么?
它最值钱的地方,是你可以不改代码就直接在线核对怀疑点。
比如方法到底慢在哪、某批参数是不是脏数据、调用是谁打进来的、线上类文件是不是你以为的版本,这些都更适合用 Arthas 当场确认。
4. 什么时候最不该只靠 jstack?
当你连续抓了几次栈,看到的热点总在变,或者怀疑问题是持续分配、序列化、加解密这类累计型开销时,就别只盯单次快照了,应该换采样画像来定性。
5. 这三个工具会互相替代吗?
不会。
更准确地说,它们经常是接力关系:先用一把工具把问题缩到合适范围,再让另一把工具把怀疑点坐实。
下一步通常会接到这些更具体的现场
- 准备直接上 Arthas,看命令怎么落到线程、方法、参数和代码确认:
Arthas 在线上排障时,最值得先掌握的 6 个命令怎么用? - 想把
jstack / jmap / jstat这些 JVM 原生工具也分清职责:线上问题排查时,jstack、jmap、jstat 分别怎么看 - 现场已经明确是 CPU 高,要沿热点线程和方法继续收证据:
Java CPU 飙高怎么排查:一套线上定位顺序 - CPU 和 GC 一起抖,想先确认时间先后和因果关系:
CPU 高和 GC 抖同时出现时,先证明谁是因谁是果? - 还需要把系统层工具一起带进来交叉看:
top、pidstat、ss、netstat、iostat 分别适合回答什么问题?
十、如果你准备把三类工具接起来
这篇更像一张“首选工具分流表”:先帮你决定第一把该用谁,不替代后面的专项文章。
如果你现在卡在工具边界,继续看这几篇会更顺:
- 线上问题排查时,jstack、jmap、jstat 分别怎么看
- Arthas 在线上排障时,最值得先掌握的 6 个命令怎么用?
- top、pidstat、ss、netstat、iostat 分别适合回答什么问题?
- 线上故障排查时,为什么很多人第一步就查错了方向?
如果现场已经落到具体症状,就按故障表象继续接:
- 高 CPU 先接 Java CPU 飙高怎么排查:一套线上定位顺序,需要把 GC 因果也拎清时,再补 CPU 高和 GC 抖同时出现时,先证明谁是因谁是果?
- 线程池队列不长、任务还是慢,就去看 线程池队列不长但任务还是慢,常见瓶颈在哪里?
- 更像方法慢、参数异常、线上代码不一致,就直接回到 Arthas 在线上排障时,最值得先掌握的 6 个命令怎么用?
- 如果 JVM 原生工具和系统层工具总是混着用,就把 线上问题排查时,jstack、jmap、jstat 分别怎么看 和 top、pidstat、ss、netstat、iostat 分别适合回答什么问题? 连着读一遍
十一、最后总结:先分清你现在缺哪种证据
async-profiler、Arthas、jstack 容易被拿来一起讨论,不是因为三者重复,而是因为它们都会出现在同一个故障现场。
但它们真正擅长的动作并不一样:
- 你想知道线程现在卡在哪,用
jstack - 你想在线核对方法、参数、调用来源和代码实现,用 Arthas
- 你想证明一段时间里的 CPU 或分配热点到底稳不稳定,用 async-profiler
现场只要先把这个问题想明白,后面无论是继续抓线程、看方法,还是补系统层工具,判断都会顺很多。