未分类 · 2025-06-30 0

arthas 使用

一、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);
    }
}