Arthas
Arthas 使用笔记
alibaba / arthas
https://github.com/alibaba/arthas
命令
https://arthas.aliyun.com/doc/commands.html
trace 方法调用路径及各节点耗时
https://arthas.aliyun.com/doc/trace.html
trace 完全限定类名 方法名
跟踪方法内部调用路径,并输出方法路径上的每个节点上耗时trace 完全限定类名 方法名 '#cost>5'
只展示耗时大于5毫秒的,方便排查慢方法
[arthas@86]$ trace demo.MathGame run
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 150 ms, listenerId: 1
`---ts=2022-06-28 11:34:09;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
`---[1.01795ms] demo.MathGame:run()
+---[30.04% 0.305773ms ] demo.MathGame:primeFactors() #24
`---[20.31% 0.206752ms ] demo.MathGame:print() #25
stack 方法被调用路径
https://arthas.aliyun.com/doc/stack.html
stack 完全限定类名 方法名
输出当前方法被调用的调用路径stack 完全限定类名 方法名 '#cost>5'
只展示耗时大于5毫秒的,方便排查慢方法
[arthas@54842]$ stack demo.MathGame primeFactors
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 69 ms, listenerId: 16
ts=2022-06-28 21:18:18;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@70dea4e
@demo.MathGame.primeFactors()
at demo.MathGame.run(MathGame.java:24)
at demo.MathGame.main(MathGame.java:16)
monitor 方法平响/成功率统计
https://arthas.aliyun.com/doc/monitor.html
monitor 完全限定类名 方法名
对方法调用进行监控,可看到平响、成功率-c 5
以5秒为统计周期,默认是120秒
[arthas@38573]$ monitor -c 5 demo.MathGame primeFactors
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 26 ms, listenerId: 3
timestamp class method total success fail avg-rt(ms) fail-rate
--------------------------------------------------------------------------------------------------
2022-06-28 20:15:48 demo.MathGame primeFactors 5 2 3 0.11 60%
thread 查看cpu占用高的线程
thread 显示线程数概览和第一页线程信息,默认按照 CPU 增量时间降序排列,只显示第一页数据。
thread -n 3 当前最忙的前 3 个线程并打印堆栈
thread id 显示指定线程的堆栈
watch 看方法入参和返回值
https://arthas.aliyun.com/doc/watch.html
watch 完全限定类名 方法名
查看方法执行的入参、异常、返回值-x
指定输出结果的属性遍历深度,默认为 1,最大值是4,-x 2
才能看到调用的入参和返回值
watch 结果中的 result 是观察表达式,默认值是 {params, target, returnObj}
即参数、this对象和返回值
watch 命令的结果里,会打印出 location 信息。location 有三种可能值:
- AtEnter 函数入口
- AtExit 函数正常return
- AtExceptionExit 函数抛出异常
示例1、方法执行异常
[arthas@54842]$ watch demo.MathGame primeFactors -x 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 32 ms, listenerId: 5
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2022-06-28 20:49:54; [cost=0.356875ms] result=@ArrayList[
@Object[][
@Integer[-61463],
],
@MathGame[
random=@Random[java.util.Random@254989ff],
illegalArgumentCount=@Integer[176],
],
null,
]
location=AtExceptionExit 表示方法执行异常,所以 returnObj 是 null
示例2、方法正常返回
[arthas@54842]$ watch demo.MathGame primeFactors -x 2
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 30 ms, listenerId: 8
method=demo.MathGame.primeFactors location=AtExit
ts=2022-06-28 20:54:25; [cost=1.681583ms] result=@ArrayList[
@Object[][
@Integer[1],
],
@MathGame[
random=@Random[java.util.Random@254989ff],
illegalArgumentCount=@Integer[309],
],
@ArrayList[
@Integer[7],
@Integer[19],
@Integer[139],
],
]
location=AtExit 表示方法正常返回
result 中第一个是入参,最后的是结果
sc 查看类信息
https://arthas.aliyun.com/doc/sc.html
sc 完全限定类名
Search-Class,查看 JVM 已加载的类信息-d
输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。
如果一个类被多个 ClassLoader 所加载,-d 结果中会出现多次,所以可以通过 sc -d 看到是否一个类被多个类加载器加载
[arthas@86]$ sc -d demo.MathGame
class-info demo.MathGame
code-source /root/math-game.jar
name demo.MathGame
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name MathGame
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-jdk.internal.loader.ClassLoaders$AppClassLoader@c387f44
+-jdk.internal.loader.ClassLoaders$PlatformClassLoader@1152c911
classLoaderHash c387f44
Affect(row-cnt:1) cost in 22 ms.
sm 查看类的方法信息
https://arthas.aliyun.com/doc/sm.html
sm 完全限定类名
Search-Method,查看已加载的类的方法信息-d
展示每个方法的详细信息
[arthas@86]$ sm demo.MathGame
demo.MathGame <init>()V
demo.MathGame main([Ljava/lang/String;)V
demo.MathGame run()V
demo.MathGame print(ILjava/util/List;)V
demo.MathGame primeFactors(I)Ljava/util/List;
Affect(row-cnt:5) cost in 7 ms.
ognl 执行ognl表达式
https://arthas.aliyun.com/doc/ognl.html
ognl 'ognl表达式'
执行 ognl 表达式
OGNL(Object-Graph Navigation Language) 是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
https://commons.apache.org/proper/commons-ognl/index.html
1、ognl 调用静态方法
[arthas@90922]$ ognl '@java.lang.System@currentTimeMillis()'
@Long[1656678870758]
[arthas@90922]$ ognl '@java.lang.System@out.println("hell")'
null
[arthas@6]$ ognl '@java.security.Security@getProperty("networkaddress.cache.ttl")'
null
[arthas@6]$ ognl '@sun.net.InetAddressCachePolicy@get()'
@Integer[30]
2、执行多行表达式,赋值给临时变量,返回一个List
[arthas@90922]$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
@ArrayList[
@String[/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre],
@String[OpenJDK Runtime Environment],
]
jad 反编译类/方法
https://arthas.aliyun.com/doc/jad.html
jad 完全限定类名
反编译指定的类jad 完全限定类名 方法名
反编译指定的方法
默认情况下,反编译结果里会带有ClassLoader信息,通过 –source-only 选项,可以只打印源代码。
[arthas@54842]$ jad demo.MathGame
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@70dea4e
+-sun.misc.Launcher$ExtClassLoader@1b6d3586
Location:
/Users/masi/.arthas/lib/3.6.2/arthas/math-game.jar
/*
* Decompiled with CFR.
*/
package demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MathGame {
private static Random random = new Random();
private int illegalArgumentCount = 0;
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
while (true) {
/*16*/ game.run();
/*17*/ TimeUnit.SECONDS.sleep(1L);
}
}
public void run() throws InterruptedException {
try {
/*23*/ int number = random.nextInt() / 10000;
/*24*/ List<Integer> primeFactors = this.primeFactors(number);
/*25*/ MathGame.print(number, primeFactors);
}
catch (Exception e) {
/*28*/ System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
}
}
public static void print(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer(number + "=");
/*34*/ for (int factor : primeFactors) {
/*35*/ sb.append(factor).append('*');
}
/*37*/ if (sb.charAt(sb.length() - 1) == '*') {
/*38*/ sb.deleteCharAt(sb.length() - 1);
}
/*40*/ System.out.println(sb);
}
public List<Integer> primeFactors(int number) {
/*44*/ if (number < 2) {
/*45*/ ++this.illegalArgumentCount;
throw new IllegalArgumentException("number is: " + number + ", need >= 2");
}
ArrayList<Integer> result = new ArrayList<Integer>();
/*50*/ int i = 2;
/*51*/ while (i <= number) {
/*52*/ if (number % i == 0) {
/*53*/ result.add(i);
/*54*/ number /= i;
/*55*/ i = 2;
continue;
}
/*57*/ ++i;
}
/*61*/ return result;
}
}
Affect(row-cnt:1) cost in 451 ms.
安装 Arthas
https://arthas.aliyun.com/doc/install-detail.html
在线安装 Arthas
wget https://arthas.aliyun.com/arthas-boot.jar
下载只有 100 多 kb 的 arthas-boot.jarjava -jar arthas-boot.jar
启动后会自动检测 jvm 进程,输入序号选择一个 jvm 进程,然后开始自动下载需要的其他 jar 包,完成后会自动 attach 到进程上即可开始使用。
java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.6.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 74225
[2]: 70338
[3]: 59427 org.jetbrains.idea.maven.server.RemoteMavenServer36
[4]: 51391 com.intellij.database.remote.RemoteJdbcServer
1
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.6.2?mirror=aliyun
[INFO] File size: 12.88 MB, downloaded size: 2.00 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 3.86 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 5.50 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 6.81 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 8.48 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 10.27 MB, downloading ...
[INFO] File size: 12.88 MB, downloaded size: 12.11 MB, downloading ...
[INFO] Download arthas success.
[INFO] arthas home: /Users/masi/.arthas/lib/3.6.2/arthas
[INFO] Try to attach process 74225
[WARN] Current VM java version: 1.8 do not match target VM java version: 11, attach may fail.
[WARN] Target VM JAVA_HOME is /Applications/DataGrip.app/Contents/jbr/Contents/Home, arthas-boot JAVA_HOME is /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre, try to set the same JAVA_HOME.
java.io.IOException: Non-numeric value found - int expected
at sun.tools.attach.HotSpotVirtualMachine.readInt(HotSpotVirtualMachine.java:299)
at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:63)
at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:79)
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:103)
at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:122)
at com.taobao.arthas.core.Arthas.<init>(Arthas.java:27)
at com.taobao.arthas.core.Arthas.main(Arthas.java:151)
[WARN] It seems to use the lower version of JDK to attach the higher version of JDK.
[WARN] This error message can be ignored, the attach may have been successful, and it will still try to connect.
[INFO] Attach process 74225 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.6.2
main_class
pid 74225
time 2022-06-28 14:17:30
离线安装 Arthas
离线环境无法通过 java -jar arthas-boot.jar
自动安装,会报错:
[ERROR] Can not read arthas version from: https://arthas.aliyun.com/api/latest_version
[ERROR] Can not find Arthas under local: /root/.arthas/lib and remote repo mirror: aliyun
[ERROR] Unable to download arthas from remote server, please download the full package according to wiki: https://github.com/alibaba/arthas
从 阿里云 或 GitHub 下载得到 arthas-packaging-3.6.2-bin.zip
https://arthas.aliyun.com/download/latest_version?mirror=aliyun
https://github.com/alibaba/arthas/releases/download/arthas-all-3.6.3/arthas-bin.zip
unzip arthas-packaging-3.6.2-bin.zip -d arthas 解压到 arthas 目录,里面有 arthas-boot.jar 及需要的其他全量工具。
还是 java -jar arthas-boot.jar
启动,不会再重新下载,直接即可 attach 到进程上
# java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.6.2
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 6 /root/apps/app/lib/app-exporter-2.0.0-SNAPSHOT.jar
1
[INFO] arthas home: /root/logs/arthas-3.6.2
[INFO] Try to attach process 6
[INFO] Attach process 6 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.6.2
main_class
pid 6
time 2022-06-28 14:43:54
上一篇 Milvus
下一篇 Eclipse-MAT
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: