Arthas学习
文章目录
安装使用
(1)安装
|
|
(2)退出Arthas
直接运行 quit
或者 exit
命令。但是这不是退出 Arthas ,而是退出当前连接而已,下次还是可以继续连接 Arthas 。想完全退出 Arthas,需要使用 stop
或者 shutdown
命令;
常用命令
(1)查看仪表盘
直接运行 dashboard
,这个主要是帮助我们发现性能问题:
(2)修改日志级别
直接输入 logger
命令即可查看logger信息,包括日志的位置,对于查看系统的日志位置非常方便:
此外, logger
命令还可以用于修改日志级别:
参数 | 说明 |
---|---|
-c | 指定 classloader 的 hash ,默认为 SystemClassLoader ,例如: logger -c 1654a892 |
-l | 设置日志级别,例如: logger -n debug -c 1654a892 -l debug |
-n | 获取指定名称logger的信息,例如: logger -n debug |
(3)下载内存
可以使用 heapdump
命令下载程序的运行时内存,参数说明如下:
参数 | 说明 |
---|---|
-l | 只dump内存中的live对象,例如: heapdump -l /tmp/dump.hprof |
[file] | 指定输出文件,例如: heapdump /tmp/dump.hprof |
(4)反编译
直接使用 jad xxx.xxx.xxx.XXX
来反编译某个类:
(5)动态修改类
这个功能相关的命令为: retransform
,其限制如下:
- 不允许新增加
field
或者method
; - 正在跑的函数,没有退出不能生效;
参数说明:
参数 | 说明 |
---|---|
-c | 指定classloader加载文件,例如: retransform -c 327a647b /tmp/Test.class /tmp/Test\$Inner.class |
–classPattern [value] | 触发重新加载class文件,例如: retransform --classPattern demo.* |
-d | 删除指定id替换的条目,例如: retransform -d 1 |
–deleteAll | 删除所有替换的条目,例如: retransform --deleteAll |
-l | 列出所有替换的条目,例如: retransform -l |
[classfilePaths] | 加载指定路径的class文件,例如: retransform /tmp/Test.class |
如果需要还原修改后的类:
|
|
(6)观察方法调用
这个功能相关的命令为: watch
;相关参数和介绍如下:
参数 | 说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
express | 观察表达式 |
condition-express | 条件表达式 |
[b] | 在方法调用之前观察 |
[e] | 在方法异常之后观察 |
[s] | 在方法返回之后观察 |
[f] | 在方法结束之后(正常返回和异常返回)观察 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[x:] | 指定输出结果的属性遍历深度,默认为 1 |
注意点:
watch
命令定义了4个观察事件点,即-b
方法调用前,-e
方法异常后,-s
方法返回后,-f
方法结束后;- 4个观察事件点
-b
、-e
、-s
默认关闭,-f
默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出; - 这里要注意
方法入参
和方法出参
的区别,有可能在中间被修改导致前后不一致,除了-b
事件点params
代表方法入参外,其余事件都代表方法出参; - 当使用
-b
时,由于观察事件点是在方法调用前,此时返回值或异常均不存在;
例如使用如下命令观察方法入参和返回的参数:
|
|
一些案例场景可以查看:https://github.com/alibaba/arthas/issues/71
Arthas中Ognl默认支持的变量为如下:
|
|
(7)观察方法调用路径
trace
命令能主动搜索 class-pattern
/method-pattern
对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
condition-express | 条件表达式 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[n:] | 命令执行次数 |
#cost | 方法执行耗时 |
注意:watch
, stack
, trace
这个三个命令都支持 #cost
。
例如使用如下命令查看某个函数的调用路径,但是貌似只能查看目标函数的栈顶调用路径,不能看到栈低的调用路径,也就是说,不能查看是谁调用到了目标函数:
|
|
(8)查看ClassLoader
使用 classloader
命令可以查看classloader的继承树,urls,类加载信息;例如使用如下命令查看classloader统计信息:
|
|
查看classloader的继承树:
|
|
(9)内存编译
使用 mc
命令可以编译 .java
文件生成 .class
;可以使用 -c
选项指定classloader:
|
|
也可以通过--classLoaderClass
参数指定ClassLoader:
|
|
编译生成 .class
文件之后,可以结合 retransform
命令实现热更新代码。
注意:mc
命令有可能失败。如果编译失败可以在本地编译好 .class
文件,再上传到服务器。
(10)查看方法调用栈
前面说过可以通过 trace
命令查看方法调用路径,但是这样只能得到从当前方法往下执行的调用路径,如果想得到完整的方法调用栈,需要使用 stack
命令:
|
|
一些参数说明如下:
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 方法名表达式匹配 |
condition-express | 条件表达式 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[n:] | 执行次数限制 |
注意事项
JVM
只能 attach 同样用户下的 java 进程,需要切换到目标JVM
相同的用户下,才能使用,或者使用某个用户的身份执行命令:java -jar arthas-boot.jar --telnet-port 9998 --http-port -1
;
参考
文章作者 P1n93r
上次更新 2021-06-15