安装使用

(1)安装

1
2
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar --telnet-port 9998 --http-port -1

image-20210928171455643

(2)退出Arthas

直接运行 quit 或者 exit 命令。但是这不是退出 Arthas ,而是退出当前连接而已,下次还是可以继续连接 Arthas 。想完全退出 Arthas,需要使用 stop 或者 shutdown 命令;

常用命令

(1)查看仪表盘

直接运行 dashboard ,这个主要是帮助我们发现性能问题:

image-20210928172024450

(2)修改日志级别

直接输入 logger 命令即可查看logger信息,包括日志的位置,对于查看系统的日志位置非常方便:

image-20210928173235967

此外, 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 来反编译某个类:

image-20210928174846064

(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

如果需要还原修改后的类:

1
2
retransform -d 1
retransform --classPattern xxx.xx.xx.XXX

(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 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在;

例如使用如下命令观察方法入参和返回的参数:

1
watch com.rebuild.web.commons.UrlSafe isTrusted "{params,returnObj}" -x 3

image-20210930001103080

一些案例场景可以查看:https://github.com/alibaba/arthas/issues/71

Arthas中Ognl默认支持的变量为如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ClassLoader loader;
Class<?> clazz;
ArthasMethod method;
Object target;
Object[] params;
Object returnObj;
Throwable throwExp;
boolean isBefore;
boolean isThrow;
boolean isReturn;

(7)观察方法调用路径

trace 命令能主动搜索 class-patternmethod-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。

参数说明如下:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
condition-express条件表达式
[E]开启正则表达式匹配,默认为通配符匹配
[n:]命令执行次数
#cost方法执行耗时

注意:watchstacktrace 这个三个命令都支持 #cost

例如使用如下命令查看某个函数的调用路径,但是貌似只能查看目标函数的栈顶调用路径,不能看到栈低的调用路径,也就是说,不能查看是谁调用到了目标函数:

1
trace *UrlSafe isTrusted -v

image-20210930003032829

(8)查看ClassLoader

使用 classloader 命令可以查看classloader的继承树,urls,类加载信息;例如使用如下命令查看classloader统计信息:

1
classloader -l

image-20210930004101314

查看classloader的继承树:

1
classloader -t

image-20210930004227581

(9)内存编译

使用 mc 命令可以编译 .java 文件生成 .class ;可以使用 -c 选项指定classloader:

1
mc -c 327a647b /tmp/Test.java

也可以通过--classLoaderClass参数指定ClassLoader:

1
mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp

编译生成 .class 文件之后,可以结合 retransform 命令实现热更新代码。

注意:mc 命令有可能失败。如果编译失败可以在本地编译好 .class 文件,再上传到服务器。

(10)查看方法调用栈

前面说过可以通过 trace 命令查看方法调用路径,但是这样只能得到从当前方法往下执行的调用路径,如果想得到完整的方法调用栈,需要使用 stack 命令:

1
stack *UrlSafe isTrusted

image-20210930005256206

一些参数说明如下:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
condition-express条件表达式
[E]开启正则表达式匹配,默认为通配符匹配
[n:]执行次数限制

注意事项

  • JVM 只能 attach 同样用户下的 java 进程,需要切换到目标 JVM 相同的用户下,才能使用,或者使用某个用户的身份执行命令: java -jar arthas-boot.jar --telnet-port 9998 --http-port -1

参考