Java

async-profiler、Arthas、jstack 到底什么时候该先用哪个?

线上排障时,async-profiler、Arthas、jstack 经常一起出现,但它们拿到的不是同一种证据。`jstack` 给你线程当下停在哪,Arthas 适合在线核对方法、参数和调用来源,async-profiler 则用一段时间的采样告诉你热点是不是稳定存在。

  • Java
  • async-profiler
  • Arthas
  • jstack
  • 工具链
18 分钟阅读

线上 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 可疑
  • 某类请求参数怀疑触发了坏路径
  • 想确认线上代码实现和本地认知是否一致
  • 需要快速看线程、方法、参数,不想在多个工具之间切换

常见命令方向

  • dashboard
  • thread
  • trace
  • watch
  • stack
  • jad

如果你想看具体怎么串,站内已经有一篇更完整的拆解:

它的边界

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 高,先想知道线程现在在干什么

更贴近现场的顺序通常是:

  1. top -Hp / pidstat -t
  2. jstack
  3. 如果线程栈不够稳定,再补 async-profiler

为什么这样更稳:

  • 先用线程栈知道“此刻谁在忙”
  • 再用 profiler 证明“长期到底谁最热”

场景 2:接口慢,已经大概知道可疑方法

更贴近现场的顺序通常是:

  1. Arthas dashboard / thread
  2. Arthas trace
  3. 必要时 watch / stack

为什么:

  • 你缺的是方法级验证,不是先做全局采样画像

场景 3:线程池堆积、服务卡住,想知道在等什么

更贴近现场的顺序通常是:

  1. jstack
  2. Arthas thread
  3. 再结合数据库、连接池、下游监控

为什么:

  • 这类问题首先要回答的是等待点,而不是长期 CPU 热点

场景 4:CPU 高、对象创建多,怀疑分配热点

更贴近现场的顺序通常是:

  1. 先用 jstack 或 Arthas thread 建立方向感
  2. 再用 async-profiler 看 CPU / alloc 画像
  3. 回到热点代码做验证

为什么:

  • 这时单靠瞬时栈很容易不够,采样画像价值会更高

场景 5:怀疑线上代码、参数或调用来源不对

更贴近现场的顺序通常是:

  1. Arthas watch
  2. Arthas stack
  3. 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. 这三个工具会互相替代吗?

不会。

更准确地说,它们经常是接力关系:先用一把工具把问题缩到合适范围,再让另一把工具把怀疑点坐实。

下一步通常会接到这些更具体的现场

十、如果你准备把三类工具接起来

这篇更像一张“首选工具分流表”:先帮你决定第一把该用谁,不替代后面的专项文章。

如果你现在卡在工具边界,继续看这几篇会更顺:

如果现场已经落到具体症状,就按故障表象继续接:

十一、最后总结:先分清你现在缺哪种证据

async-profiler、Arthas、jstack 容易被拿来一起讨论,不是因为三者重复,而是因为它们都会出现在同一个故障现场。

但它们真正擅长的动作并不一样:

  • 你想知道线程现在卡在哪,用 jstack
  • 你想在线核对方法、参数、调用来源和代码实现,用 Arthas
  • 你想证明一段时间里的 CPU 或分配热点到底稳不稳定,用 async-profiler

现场只要先把这个问题想明白,后面无论是继续抓线程、看方法,还是补系统层工具,判断都会顺很多。