目录
arthas本身有一定的性能消耗,所以生产环境小心使用
arthas本身有一定的性能消耗,所以生产环境小心使用
arthas本身有一定的性能消耗,所以生产环境小心使用
文档地址:arthas (aliyun.com)
有外网的情况下
- // 下载arthas-boot.jar
- curl -O https://arthas.aliyun.com/arthas-boot.jar
- // 启动arthas-boot.jar
- java -jar arthas-boot.jar
需要注意的是,启动arthas-boot.jar后attach进程的时候,会从外网下载依赖。
以在linux服务器上离线安装为例。
即可使用
可以查看如下信息,还是很方便的。图片来自官网

这里巩固一下nonheap:非堆就是JVM留给自己用的,所有方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。
类似 jmap 命令的 heap dump 功能
dump 到指定文件:heapdump /tmp/dump.hprof
展示当前最忙的前 N 个线程并打印堆栈:(以前三个为例子)thread -n 3
显示指定线程的运行堆栈:thread id
显示一页线程信息(增量时间降序排列):thread
反编译某个类(只显示源代码):(以String为例)jad --source-only java.lang.String
反编译某个方法:(以String的charAt为例)jad --source-only java.lang.String charAt
输出当前方法被调用的调用路径
以官方例子为案例:stack demo.MathGame primeFactors
方法内部调用路径,并输出方法路径上的每个节点上耗时。个人很喜欢,可以查哪里耗时比较多!作用在方法上
限定trace次数:(以1次为例)trace 全类名 方法名 -n -1
trace 结果时间不准确问题,比如0.705196 > (0.152743 + 0.145825)
- $ trace demo.MathGame run -n 1
- Press Q or Ctrl+C to abort.
- Affect(class count: 1 , method count: 1) cost in 66 ms, listenerId: 1
- `---ts=2021-02-08 11:27:36;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@232204a1
- `---[0.705196ms] demo.MathGame:run()
- +---[0.152743ms] demo.MathGame:primeFactors() #24
- `---[0.145825ms] demo.MathGame:print() #25
这个时候可能会有没有被 trace 到的函数。比如java.* 下的函数调用默认会忽略掉。通过增加 --skipJDKMethod false参数可以打印出来。
- $ trace demo.MathGame run --skipJDKMethod false
- Press Q or Ctrl+C to abort.
- Affect(class count: 1 , method count: 1) cost in 35 ms, listenerId: 2
- `---ts=2021-02-08 11:27:48;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@232204a1
- `---[0.810591ms] demo.MathGame:run()
- +---[0.034568ms] java.util.Random:nextInt() #23
- +---[0.119367ms] demo.MathGame:primeFactors() #24 [throws Exception]
- +---[0.017407ms] java.lang.StringBuilder:<init>() #28
- +---[0.127922ms] java.lang.String:format() #57
- +---[min=0.01419ms,max=0.020221ms,total=0.034411ms,count=2] java.lang.StringBuilder:append() #57
- +---[0.021911ms] java.lang.Exception:getMessage() #57
- +---[0.015643ms] java.lang.StringBuilder:toString() #57
- `---[0.086622ms] java.io.PrintStream:println() #57
能方便的观察到指定函数的调用情况。能观察到的范围为:返回值、抛出异常、入参。
watch 命令定义了 4 个观察事件点,即 -b 函数调用前,-e 函数异常后,-s 函数返回后,-f 函数结束后。
观察表达式,默认值是
{params, target, returnObj}
代表入参、this 对象和返回值
查看第一个入参:watch 全类名 方法名 "{params[0]}" -x 2
注意:-x 表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是 1,最大是4。
有机会,发一个实战演练。下次一定🤔🤡🤔