# arthas(阿里问题排查工具)
# 使用
提供两种启动方式
- 使用arthas-boot.jar直接 java -jar启动
- 使用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
- [b]在方法调用之前观察
- [e]在方法异常之后观察
- [s]在方法返回之后观察
- [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(全局配置)
命令设置全局配置
- 输出显示格式,配置为json options json-format true
- 禁用子类匹配 options disable-sub-class true
# 火焰图(Flame Graph)
展示CPU的调用栈、显示CPU的繁忙程度 x轴=抽样次数 y轴=调用栈(每层都是一个函数)
# 可操作性
- 鼠标悬浮在每一个函数上,会显示
完整的函数名、抽样抽中的次数、占据总抽样次数的百分比。 - 点击每一个函数都可以放大显示当前调用栈
- CTRL+F可以使用正则进行函数搜索
# 如何利用火焰图分析
- 从底层看,先查看宽度大的函数(代表执行用时多或次数多),鼠标点击放大查看。
- 打开单个函数视图后,从顶层看,从宽度最大的一个函数顶进行分析。