Java虚拟机 动态追踪
时间:2019/3/15 11:59:51
参考:
Java动态追踪技术探究#
Arthas(阿尔萨斯)#
阿里开源的Java诊断工具,采用命令行方式,支持Tab自动补全,相较于JDK提供的 jps jstack jinfo 等原生命令更全面更好用。
可以做什么#
- 监控JVM实时运行状况。
- 监控方法的调用耗时。
- 观察方法的返回值、抛出异常、入参等。
- 方法执行记录,需要时可以使用记录的参数等信息多次调用测试。
- 支持
ongl表达式。 - 支持
Tab自动补全。 - ...
基础知识#
-
表达式核心变量,。
Arthas命令参数会使用该类进行一些逻辑判断,比如params.length == 1method.name="abc"。参考: 特殊用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
public class Advice { //本次调用类所在的 ClassLoader private final ClassLoader loader; //本次调用类的 Class 引用 private final Class<?> clazz; //本次调用方法反射引用 private final ArthasMethod method; //本次调用类的实例 private final Object target; //本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组 private final Object[] params; //本次调用返回的对象。当且仅当 isReturn==true 成立时候有效,表明方法调用是以正常返回的方式结束。如果当前方法无返回值 void,则值为 null private final Object returnObj; //本次调用抛出的异常。当且仅当 isThrow==true 成立时有效,表明方法调用是以抛出异常的方式结束。 private final Throwable throwExp; //辅助判断标记,当前的通知节点有可能是在方法一开始就通知,此时 isBefore==true 成立,同时 isThrow==false 和 isReturn==false,因为在方法刚开始时,还无法确定方法调用将会如何结束。 private final boolean isBefore; //辅助判断标记,当前的方法调用以抛异常的形式结束。 private final boolean isThrow; //辅助判断标记,当前的方法调用以正常返回的形式结束。 private final boolean isReturn; }- 常用过滤条件。
'#cost >0'耗时大于零。
命令#
基础命令#
cls清空屏幕。help查看帮助信息。session查看当前session。reset重置增强类,重置使用Arthas过程对类的更改。version版本号。history命令历史。quit退出当前客户端。stop shutdown关闭Arthas所有客户端都会退出。keymap快捷键。
其它命令#
dashboard查看进程整体运行情况概要界面。thread查看线程堆栈信息。thread显示所有线程。thread id指定线程信息。thread -n number查看占用率最高的前number个线程的堆栈信息。thread -b查看阻塞其它线程的线程。thread -i time: 线程CPU时间占用时间统计。thread -n 3 -i 1000指定采样间隔。-
jvm查看当前JVM信息。 -
COUNT: JVM当前活跃的线程数。 DAEMON-COUNT: JVM当前活跃的守护线程数。PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数。STARTED-COUNT: 从JVM启动开始总共启动过的线程次数。DEADLOCK-COUNT: JVM当前死锁的线程数。MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数。OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数。-
sysprop查看系统属性。 -
sysprop查看所有属性。 sysprop java.version查看单个属性。sysprop user.country country设置属性。sysenv查看当前JVM的环境属性。vmoption:查看虚拟机选项配置。vmoption查看配置。vmoption PrintGCDetails true设置虚拟机选项配置。logger: 查看所有logger信息。logger查看所有。logger -n org.springframework.web指定名字查看。mbean查看 Mbean 的信息。sc搜索虚拟机已经加载的类信息。sc com.sun.xiaotian.blogger.*搜索指定包下面的类。sc -d com.sun.xiaotian.blogger.util.PinYin打印类的详细信息。sc -df com.sun.xiaotian.blogger.model.ArticleInfo输出类的成员变量。sc -df -x 3 com.sun.xiaotian.blogger.model.ArticleInfo成员变量深度为3。 10sm搜索类的方法。sm java.lang.String搜索指定类的方法。sm -d java.lang.String搜索指定类的方法,并展示方法的详细信息。sm -d java.lang.String toString搜索指定类的指定方法。dumpdump已加载的类到特定目录。dump com.sun.xiaotian.blogger.*dump 指定包。heapdumpdump 堆信息到指定目录。heapdump /tmp/dump.hprofdump到指定目录。heapdump --live /tmp/dump.hprof只 dump live 对象。jad反编译类文件。jad com.sun.xiaotian.blogger.BloggerRun反编译指定类。jad --source-only com.sun.xiaotian.blogger.BloggerRun反编译指定类,只显示源码。jad com.sun.xiaotian.blogger.BloggerRun main反编译指定函数。jad -c @6767c1fc com.sun.xiaotian.blogger.BloggerRun指定类加载器。classloader查看classloader的继承树,urls,类加载信息。classloader类加载器的统计信息。classloader -t查看类加载器的继承树。classloader -a查看所有类加载器(危险)。classloader -c 1b6d3586 -r java/lang/String.class使用类加载器查找类。classloader -c 3d4eac69 --load demo.MathGame使用类加载器加载类。mc内存编译器,编译.java文件。redefine加载外部class。monitor监控方法调用。monitor -c 5 demo.MathGame primeFactors监控方法调用 调用次数、成功次数、失败次数。-c指定统计周期(单位秒)。watch观察方法参数、返回值等。-b方法调用之前-e方法异常之后-s方法返回之后-f方法结束之后(正常返回合异常返回)。watch demo.MathGame primeFactors "{params,returnObj}" -x 2观察方法出参和返回值,深度为2。watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b观察方法入参。watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2同时观察方法调用前和方法返回后,执行两次。watch demo.MathGame primeFactors "{params,target}" -x 3调整参数便利深度a.b.c。watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"条件表达式。watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2观察异常信息。watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2按照耗时进行过滤。watch demo.MathGame primeFactors 'target'观察当前对象中的属性。trace方法内部调用路径,及每个调用的耗时(方法内部调用)。trace com.sun.xiaotian.blogger.web.FileInfoController getContentByFilePath查看对应方法里的方法调用及耗时。trace *StringUtils isBlank通配符。trace -j com.sun.xiaotian.blogger.web.FileInfoController getContentByFilePath查看对应方法里的方法调用及耗时。过滤掉JDK内部方法。trace demo.MathGame run '#cost > 10'耗时大于10毫秒。trace -E com.test.ClassA|org.test.ClassB method1|method2|method3跟踪多个方法。stack打印方法的调用堆栈,及执行耗时(从哪里调用到方法)。stack demo.MathGame primeFactors打印方法调用堆栈。stack demo.MathGame primeFactors 'params[0]<0' -n 2根据参数过滤,限制执行两次。stack demo.MathGame primeFactors '#cost>5'根据耗时过滤。tt: TimeTunnel 时空隧道,记录下方法调用时的现场日志(入参、出参、返回值)等,方便后续模拟调用。tt -t com.sun.xiaotian.blogger.web.FileInfoController getContentByFilePath: 记录方法的调用日志。tt -t -n com.sun.xiaotian.blogger.web.FileInfoController getContentByFilePath: 记录方法的调用日志 ` 记录三次,方法调用量比较大时使用。、tt -t *Test print params.length==1方法重载的情况下,只记录参数长度为一的方法执行记录。tt -t *Test print 'params[1] instanceof Integer'方法重载的情况下,只记录参数类型为指定类型的方法执行记录。tt -t *Test print params[0].mobile=="13989838402"方法重载的情况下,只记录参数值为指定值的的方法执行记录。tt -l查看记录的执行日志。tt -s 'method.name=="getContentByFilePath"'查找指定方法名字的记录。tt -i 1000查看调用信息,非常详细。-
tt -i 1000 -p使用记录的日志重新调用一次, 可以指定调用次数、调用间隔等参数。 -
options设置Arthas选项,设置属性options json-format true。 unsafe是否可以对系统级别的类进行增强,慎重使用,默认false。dump是否支持被增强的类dump到外部文件中。默认false,如果打开则会 dump 到application-directory/arthas-class-dump目录。json-format是否支持 json 序列化输出。默认false,开启之后回打印实际的返回值。disable-sub-class是否禁用字类匹配,默认false默认关闭。打开之后不会匹配字类,缩小匹配范围。batch-re-transform是否支持对匹配到的类批量进行retransform操作。默认true。debug-for-asm打印 ASM 相关的调试信息,默认false。save-result是否开启执行结果存日志功能,默认false。打开之后所有的命令执行结果都会保存到~/logs/arthas-cache/result.log中。job-timeout异步后台任务的默认超时时间。超过时间任务自动停止。时间格式:1d 2h 3m 25s -> 天 小时 分 秒。pwd返回当前工作目录。cat查看文件内容。
部署使用#
Arthas 支持单机版本使用,也支持 server 模式。在单机模式下,需要登录需要监控的机器,然后启动 Arthas 进行使用。在 server 模式下,需要先启动一个 server 服务,然后在需要监控的机器上启动一个 arthas 注册到服务器上,注册成功之后会有一个 代理Id,然后即可通过Web界面监控注册的机器。
常用命令#
- 查看帮助信息:
java -jar arthas-boot.jar -h - 简单启动:
java -jar arthas-boot.jar - 启动 server:
java -jar -Dserver.port=8080 arthas-tunnel-server.jar,默认 web 端口是8080, 代理端口是7777。 - 启动时注册到 server:
java -jar arthas-boot.jar --tunnel-server 'ws://192.168.0.201:7777/ws'
单机版启动: java -jar arthas-boot.jar pid
server 版启动:
- 启动Server:
java -jar -Dserver.port=8080 arthas-tunnel-server.jar - 注册:
java -jar arthas-boot.jar --tunnel-server 'ws://192.168.0.201:7777/ws
启动成功之后访问: http://ip:8080,然后输入 代理Id 即可连接。