# arthas(阿里问题排查工具)

# 使用

提供两种启动方式

  1. 使用arthas-boot.jar直接 java -jar启动
  2. 使用as.sh脚本启动

# 常用命令

cmd
watch 观察指定方法调用情况
tt 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
trace
profiler 能帮助生成火焰图,展示CPU的调用栈、显示CPU的繁忙程度
dashboard 打开面板,能即时查看Thread,Memory,GC,Runtime参数
jad 反编译类;同时也会打印出类的ClassLoader和Location
history 打印历史执行的命令
options 命令设置全局配置
jvm 查看当前JVM信息

# watch

观察指定方法调用情况

  • 该方法定义了4个观察点,如下;默认开启-f;注意:除了-b事件点params代表入参,其余事件点都代表出参,因此要注意方法可能会修改params
  1. [b]在方法调用之前观察
  2. [e]在方法异常之后观察
  3. [s]在方法返回之后观察
  4. [f]在方法结束之后(正常返回和异常返回)观察

案例 查某个方法调用的入参、返回值和异常

$ watch demo.MathGame primeFactors "{params,target,throwExp}" -x 3

观察第一个入参

$ watch demo.MathGame primeFactors "{params[0]}" -x 3

按耗时过滤

$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2

按条件过滤(params[0]是int类型)

$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"

观察当前对象的某个属性(field_name是this对象的某个类属性)

$ watch demo.MathGame primeFactors 'target.field_name'

常用参数 -x

代表参数深度,默认为1

-n

执行几次,-n 2 表示执行2次

# tt

方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测

案例 记录方法的调用现场

$ tt -t 类全限定名 方法名

指定记录3次数,自动终止

$ tt -t -n 3

解决方法重载

$ tt -t *Test print params.length==1

解决指定参数

$ tt -t *Test print params[0].mobile=="13989838402"

查看当前arthas会话的tt记录

$ tt -l

查看某一次的记录的详细信息

$ tt -i 1005

重调一次(replay-times重放次数,replay-interval重放间隔ms)

$ tt -i 1005 -p --replay-times=3 --replay-interval=5000

与watch命令区别的意义 官方文档解释:

tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。

# trace

方法内部调用路径,并输出方法路径上的每个节点上耗时

案例 看方法调用路径

$ trace 类全限定名 方法名

增加监控限制次数(3次)

$ trace -n 3 类全限定名 方法名

不跳过JDK方法(默认跳过)

$ trace --skipJDKMethod false 类全限定名 方法名

据调用耗时过滤(耗时大于10ms才显示)

$ trace 类全限定名 方法名 '#cost>10'

实现原理

trace实际上是在每一个invokevirtual 前后插入代码,然后统计调用的时间。 trace本身只能拿到当前method的字节码,所以它只能trace当前method里的 invokevirtual,再深层的invokevirtual,它并不能知道。

# thread

查看当前线程信息,查看线程的堆栈

案例 展示所有线程信息

$ thread -all

打印出当前最忙的前3个线程堆栈

$ thread -n 3

找出当前阻塞其他线程的线程(目前只支持找出synchronized关键字阻塞住的线程)

$ thread -b

查看指定状态的线程

$ thread --state WAITING

列出1000ms内最忙的3个线程栈

$ thread -n 3 -i 1000

显示指定线程的运行堆栈

$ thread 1

# profiler

本质是使用async-profiler工具提供的能力: async-profiler (opens new window) 能帮助生成火焰图。 在arm64机器上暂时无法使用arthas的profiler,因此直接

# 使用方法

启动采样

$ profiler start

获取已采集的sample的数量

$ profiler getSamples

查看profiler状态(可知采样执行了多久时间)

$ profiler status

停止profiler,生成svg格式结果

$ profiler stop --file /tmp/output.svg

# jad

反编译类;同时也会打印出类的ClassLoader和Location。

$ jad 类全路径

# options(全局配置)

命令设置全局配置

  1. 输出显示格式,配置为json options json-format true
  2. 禁用子类匹配 options disable-sub-class true

# 火焰图(Flame Graph)

展示CPU的调用栈、显示CPU的繁忙程度 x轴=抽样次数 y轴=调用栈(每层都是一个函数)

# 可操作性

  1. 鼠标悬浮在每一个函数上,会显示完整的函数名、抽样抽中的次数、占据总抽样次数的百分比
  2. 点击每一个函数都可以放大显示当前调用栈
  3. CTRL+F可以使用正则进行函数搜索

# 如何利用火焰图分析

  1. 从底层看,先查看宽度大的函数(代表执行用时多或次数多),鼠标点击放大查看。
  2. 打开单个函数视图后,从顶层看,从宽度最大的一个函数顶进行分析。
修改于: 8/11/2022, 3:17:56 PM