一、trace 查看方法的耗时
-n 参数指定捕捉结果的次数
[arthas@5848]$ trace org.example.service.StudentService say -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 27 ms, listenerId: 6
`---ts=2025-09-17 10:29:29.071;thread_name=http-nio-8080-exec-1;id=23;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@5bbc9f97
`---[0.266447ms] org.example.service.StudentService:say()
+---[31.81% 0.084758ms ] org.example.dao.Student1Dao:say1() #27
+---[14.56% 0.038802ms ] org.example.dao.Student2Dao:say2() #28
`---[2.57% 0.006853ms ] org.example.util.StudentUtils:trim() #29
二、watch 查看方法的入参、成员变量、返回值、抛出异常
函数执行数据观测,能方便的观察到指定函数的调用情况。
能观察到的范围为:方法的入参、成员变量、返回值、抛出异常,通过编写 OGNL 表达式进行对应变量的查看。
target:表示对象实例
-b before 在方法调用前观察 方法执行前
-e exception 在方法抛出异常时观察 方法抛出异常后
-s success 在方法正常返回时观察 方法正常返回后
-f finish 在方法结束时观察(默认) 方法执行后(无论成功或异常)
[arthas@5848]$ watch org.example.service.StudentService say '{params, target, returnObj, throwExp}' -x 3 -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 18 ms, listenerId: 7
method=org.example.service.StudentService.say location=AtExit
ts=2025-09-17 10:30:41.800; [cost=0.16112ms] result=@ArrayList[
@Object[][
@String[zhangsan],
],
@StudentService[
student1Dao=@Student1Dao[
],
student2Dao=@Student2Dao[
],
staticMap1=@HashMap[
@String[a]:@String[a1],
@String[b]:@String[b1],
],
value1=@String[abcd],
],
@String[Hello zhangsan],
null,
]
[arthas@5848]$ watch org.example.service.StudentService say '{params, target.value1, returnObj, throwExp}' -x 3 -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 19 ms, listenerId: 8
method=org.example.service.StudentService.say location=AtExit
ts=2025-09-17 10:31:06.415; [cost=0.159247ms] result=@ArrayList[
@Object[][
@String[zhangsan],
],
@String[abcd],
@String[Hello zhangsan],
null,
]
-x 3 是指定输出结果的属性遍历深度,默认为 1
三、stack 查看方法的调用链路
查看方法的调用链路
[arthas@5848]$ stack org.example.service.StudentService say -n 1
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 19 ms, listenerId: 10
ts=2025-09-17 10:36:56.662;thread_name=http-nio-8080-exec-8;id=30;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@5bbc9f97
@org.example.service.StudentService.say()
at org.example.controller.StudentController.say(StudentController.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1070)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
四、getstatic 查看静态变量
[arthas@5848]$ getstatic org.example.service.StudentService staticMap1
field: staticMap1
@HashMap[
@String[a]:@String[a1],
@String[b]:@String[b1],
]
五、vmtool 查看实例
[arthas@5848]$ vmtool --action getInstances --className org.example.service.StudentService --express 'instances.length'
@Integer[1]
[arthas@5848]$ vmtool --action getInstances --className org.example.service.StudentService --express 'instances[0].value1'
@String[abcd]
七、jad 查看反编译的代码
jad 查看反编译的代码
[arthas@8140]$ jad --source-only org.example.service.StudentService say
public String say(String name) {
/*27*/ String result1 = this.student1Dao.say1(name);
/*28*/ String result2 = this.student2Dao.say2(name);
/*29*/ String trim = StudentUtils.trim((String)name);
/*30*/ String a = "aaa";
/*31*/ String b = "bbb";
/*32*/ return String.format("Hello %s", name);
}
jad 把反编译的代码,输出到指定文件
[arthas@8140]$ jad --source-only org.example.service.StudentService > /tmp/StudentService.java
redirect output file will be: /tmp/StudentService.java
八、mc 编译代码
Memory Compiler/内存编译器编译,java文件生成.class文件。
[arthas@8140]$ mc /tmp/StudentService.java -d /tmp
Memory compiler output:
/tmp/org/example/service/StudentService.class
Affect(row-cnt:1) cost in 34 ms.
九、retransform 热更新代码
[arthas@8140]$ retransform /tmp/org/example/service/StudentService.class
retransform success, size: 1, classes:
org.example.service.StudentService
看到代码已变动
[arthas@8140]$ jad --source-only org.example.service.StudentService say
public String say(String name) {
/*24*/ String result1 = this.student1Dao.say1(name);
/*25*/ String result2 = this.student2Dao.say2(name);
/*26*/ String trim = StudentUtils.trim((String)name);
/*27*/ String a = "aaa";
/*28*/ String b = "bbb";
/*29*/ return String.format("Hi %s", name);
}
十、monitor
方法执行监控
monitor 命令是一个非实时返回命令.
十一、heapdump
dump 到指定文件
heapdump /tmp/heapdump.hprof
heapdump arthas-output/dump.hprof
dump 到临时文件
heapdump
生成文件在arthas-output目录,可以通过浏览器下载: http://localhost:8563/arthas-output/
十二、thread
查看所有线程
[arthas@1]$ thread
[arthas@1]$ thread --state BLOCKED
测试代码
public class StudentService {
private Student1Dao student1Dao = new Student1Dao();
private Student2Dao student2Dao = new Student2Dao();
private static final Map<String, String> staticMap1;
private String value1 = "abcd";
static {
staticMap1 = new HashMap<>();
staticMap1.put("a", "a1");
staticMap1.put("b", "b1");
}
public String say(String name) {
String result1 = student1Dao.say1(name);
String result2 = student2Dao.say2(name);
String trim = StudentUtils.trim(name);
String a = "aaa";
String b = "bbb";
return String.format("Hello %s", name);
}
}