1 简介
arthas是阿里推出的一款开源的java问题诊断工具,支持JDK6+,支持Linux/Mac/Windows系统。通过该工具,做如下事情:
- 查看JVM信息
- 查看class/classloader信息
- 监控方法运行信息
- 查看profiler/火焰图
他可以解决如下问题。
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
官方文档讲的很清楚,我这里只是把自己认为基础和常用的列下来。接下来,我将会讲解基本的用户并且回答这些问题。
2 基本使用
-
下载jar包
> curl -O https://alibaba.github.io/arthas/arthas-boot.jar -
启动一个demo进程 该进程的作用是作为一个运行的进程,会被arthas来监控。
> curl -O https://alibaba.github.io/arthas/arthas-demo.jar > java -jar arthas-demo.jar -
启动arthas进程
> java -jar arthas-boot.jar * [1]: 4409 com.chris.Application [2]: 1431 org.jetbrains.idea.maven.server.RemoteMavenServer36 [3]: 4807 org.jetbrains.jps.cmdline.Launcher [4]: 4408 org.jetbrains.jps.cmdline.Launcher [5]: 840 [6]: 7006 arthas-demo.jar # 这个为启动的arthas-demo进程。接下来输入数字6,就可以进入监控控制台了。输入数字之后,就可以进入控制台了。截图如下:

- 基本命令使用
- 输入dashboard,查看当前进程的信息
$ dashboard
图中ID为Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应。
- 通过watch查看方法的返回结果
$ watch demo.MathGame primeFactors returnObj # 查看类demo.MathGame的primeFactors方法的返回值 Press Q or Ctrl+C to abort. Affect(class-cnt:1 , method-cnt:1) cost in 40 ms. ts=2020-01-20 14:21:54; [cost=2.641688ms] result=@ArrayList[ @Integer[2], @Integer[5], @Integer[23], @Integer[677], ]
- 输入dashboard,查看当前进程的信息
- 退出arthas
如果只是断开连接,但是要保证目标进程上的arthas仍然继续运行,使用命令quit或者exit。
如果完全退出arthas,终止arthas的运行,使用命令stop或者shutdown。
3 基础导航命令
help
查看命令帮助信息
[arthas@11912]$ help
NAME DESCRIPTION
help Display Arthas Help
keymap Display all the available keymap for the specified connection.
sc Search all the classes loaded by JVM
sm Search the method of classes loaded by JVM
classloader Show classloader info
// 省略其他
grep
匹配查找,和linux里的grep命令类似
[arthas@11912]$ keymap | grep line
"\C-a" Ctrl + a beginning-of-line
"\C-e" Ctrl + e end-of-line
"\C-k" Ctrl + k kill-line
"\C-j" Ctrl + j accept-line
"\C-m" Ctrl + m accept-line
// 省略其他
pwd
返回当前的工作目录,和linux命令类似
cls
清空当前屏幕区域
history
打印命令历史
quit
退出当前arthas客户端,断开连接,但arthas的运行不受影响。
stop/shutdown
完全退出arthas,终止arthas的运行
4 常用命令
dashboard
当前系统的实时数据面板。 使用命令如下:
$ dashboard
结果如下:

jvm
查看当前JVM信息。查看的信息包括虚拟机启动参数、类加载信息、编译信息、GC回收器、内存管理器、内存使用情况、操作系统和线程信息。
$ jvm
sc
“search-class”的简写,查看JVM已经加载的类信息。这个命令支持的参数有 [d]、[E]、[f] 和 [x:]
使用示例。
- 模糊搜索
$ sc demo.* # 查看类路径以demo开头的所有类 - 打印类的详细信息
$ sc -d -f demo.MathGame # 查看类demo.MathGame的详细信息,例如类加载器信息和属性信息等。
sm
“search-method”的简写,查看已经加载过的类的方法信息。支持的参数有 [d]、[E]。
示例
[arthas@14439]$ sm java.lang.String # 查看java.lang.String的方法信息,可以加上`-d`参数来打印详细信息
java.lang.String <init>([BII)V
java.lang.String <init>([BLjava/nio/charset/Charset;)V
java.lang.String <init>([BLjava/lang/String;)V
java.lang.String <init>([BIILjava/nio/charset/Charset;)V
java.lang.String <init>([BIILjava/lang/String;)V
java.lang.String <init>([CZ)V
java.lang.String <init>(Ljava/lang/StringBuilder;)V
java.lang.String <init>(Ljava/lang/StringBuffer;)V
java.lang.String <init>([B)V
java.lang.String <init>([III)V
java.lang.String <init>()V
java.lang.String <init>([C)V
java.lang.String <init>(Ljava/lang/String;)V
java.lang.String <init>([CII)V
java.lang.String <init>([BI)V
java.lang.String <init>([BIII)V
java.lang.String equals(Ljava/lang/Object;)Z
java.lang.String toString()Ljava/lang/String;
# 省略其他
monitor
对方法的执行进行监控,监控指标包括调用次数、成功次数、失败次数、平均RT和失败率。可以含有的参数有 [E]和-c。
注意:这个命令为一个非实时的命令。输入该命令之后,后台运行的任务会每个一段时间打印出监控信息。
示例
$ monitor -c 5 demo.MathGame primeFactors # 统计周期为5秒。监控类demo.MathGame的primeFactors方法的监控信息。
watch
对方法的入参、返回值和抛出的异常进行查看,通过编写 OGNL 表达式进行对应变量的查看。支持的参数如下表所示。
| 参数 | 说明 |
|---|---|
| class-pattern | 类名表达式匹配 |
| method-pattern | 方法名表达式匹配 |
| express | 观察表达式,指定要观察的指标,比如,参数(params)、返回值(returnObj)、观察目标(target) |
| condition-express | 条件表达式。只有满足条件表达式的结果会打印出来 |
| -b | 启用方法调用之前的观察点,默认关闭 |
| -e | 启用方法异常时的观察点,默认关闭 |
| -s | 启用方法返回之后的观察点,默认关闭 |
| -f | 启用方法结束(包括正常返回和异常返回)之后的观察点,默认打开 |
| -E | 开启正则表达式匹配,默认为通配符匹配 |
| -x | 指定输出结果的属性遍历深度,默认为1。例如,对于List,-x 2才会打印类的元素的信息。 |
示例
- 观察方法出参和返回值
# 打印出类demo.MathGame的primeFactors方法的params和returnObj信息。 # 因为此时-f默认开启,即方法结束,所以params代表出参 # (有别于入参,因为方法的参数可能会在方法体中被改变。),returnObj # 代表返回结果。方法已经结束,所以returnObj是有值的。 $ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[ @Object[][ @Integer[535629513], ], @ArrayList[ @Integer[3], @Integer[19], @Integer[191], @Integer[49199], ], ] - 查看方法运行后的类的属性信息
# 查看方法运行后的类的属性值。这里指定-x 2才可以查看引用类型 # Random的属性的具体值。 $ watch demo.MathGame primeFactors 'target' -x 2 Affect(class-cnt:1 , method-cnt:1) cost in 26 ms. ts=2020-01-20 16:13:59; [cost=0.195068ms] result=@MathGame[ random=@Random[ serialVersionUID=@Long[3905348978240129619], seed=@AtomicLong[226575380786213], multiplier=@Long[25214903917], addend=@Long[11], mask=@Long[281474976710655], DOUBLE_UNIT=@Double[1.1102230246251565E-16], BadBound=@String[bound must be positive], BadRange=@String[bound must be greater than origin], BadSize=@String[size must be non-negative], seedUniquifier=@AtomicLong[-3282039941672302964], nextNextGaussian=@Double[0.0], haveNextNextGaussian=@Boolean[false], serialPersistentFields=@ObjectStreamField[][isEmpty=false;size=3], unsafe=@Unsafe[sun.misc.Unsafe@6f2b958e], seedOffset=@Long[24], ], illegalArgumentCount=@Integer[3349], ]
profiler
使用async-profiler生成火焰图。profiler命令支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。
使用步骤如下:
$ profiler start
Started [cpu] profiling
$ profiler stop
profiler output file: /tmp/demo/arthas-output/20191125-135546.svg
关于火焰图,之后的博客再讲。
5 问题解答
-
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
回答:使用sc命令可以查看类加载的信息。 -
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
回答:使用jad命令来反编译class类信息,从而判断代码是否是用户提交的代码。 -
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
回答:可以使用watch命令来查看方法入参、返回结果和类的属性信息。 -
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
回答:可以使用watch命令来查看方法入参、返回结果和类的属性信息,结果条件表达式只打印指定的用户的信息。 -
是否有一个全局视角来查看系统的运行状况?
回答:使用dashboard来查看系统的运行情况。 -
有什么办法可以监控到JVM的实时运行状态?
回答:使用jvm命令来查看jvm的运行状态。 -
怎么快速定位应用的热点,生成火焰图? 回答:使用profiler命令