Arthas JVM 调优工具

发布时间 2023-05-04 16:26:02作者: little_lunatic

阿里巴巴开源的一个 JVM 调优工具 —— arthas(阿尔萨斯)。

一、安装

curl -O https://alibaba.github.io/arthas/arthas-boot.jar

如果下载速度太慢,可以用gitee上的源

curl -O https://arthas.gitee.io/arthas-boot.jar

二、启动

java -jar arthas-boot.jar 

arthas 在启动时会检测本机运行的 jvm 进程,然后让用户选择需要绑定的进程,后面的操作都是针对选定的进程的。

[INFO] Download arthas success.
[INFO] arthas home: C:\Users\MH\.arthas\lib\3.6.8\arthas
[INFO] Try to attach process 21752
[INFO] Found java home from System Env JAVA_HOME: D:\Java\JDK1.8_64
[INFO] Attach process 21752 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.8
main_class
pid        21752
time       2023-05-04 15:33:32

出现此页面 arthas 启动成功。

三、使用 Arthas 解决问题

3.1 CPU占用过高

## 列出线程详细信息
[arthas@21752]$ thread
Threads Total: 156, NEW: 0, RUNNABLE: 12, BLOCKED: 0, WAITING: 108, TIMED_WAITING: 21, TERMINATED: 0, Internal threads:
 15
ID         NAME                              GROUP                 PRIORITY   STATE      %CPU        TIME       INTERRUPTE DAEMON     
16         http-nio-8080-exec-2              main                  5          RUNNABLE   99          0:25       false      true       
29         Attach Listener                   system                9          RUNNABLE   0           0:0        false      true 
 
## 通过 thread + ID 输出该线程的栈信息定位问题
[arthas@2467]$ thread 16
"http-nio-8080-exec-2" Id=16 RUNNABLE
    at com.spareyaya.jvm.service.EndlessLoopService.service(EndlessLoopService.java:19)
    at com.spareyaya.jvm.controller.JVMController.endlessLoop(JVMController.java:30)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

3.2 死锁

## thread -b 检查死锁
[arthas@2997]$ thread -b
"Thread-3" Id=29 BLOCKED on java.lang.Object@3f20bf9 owned by "Thread-4" Id=30
    at com.spareyaya.jvm.service.DeadLockService.service1(DeadLockService.java:27)
    -  blocked on java.lang.Object@3f20bf9
    -  locked java.lang.Object@2fea801a <---- but blocks 1 other threads!
    at com.spareyaya.jvm.controller.JVMController.lambda$deadLock$0(JVMController.java:37)
    at com.spareyaya.jvm.controller.JVMController$$Lambda$456/748979989.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)

3.3 内存泄漏

用 dashboard 命令来动态查看内存情况,如果内存使用率在不断上升,而且 gc 后也不下降,后面还发现 gc 越来越频繁,很可能就是内存泄漏了。

这个时候我们可以直接用 heapdump 命令把内存快照 dump 出来,作用和 jmap 工具一样,然后把得到的 dump 文件使用 MAT 堆内存分析工具 MemoryAnalyzer.exe 分析

[arthas@23581]$ heapdump --live /root/jvm.hprof
Dumping heap to /root/jvm.hprof...
Heap dump file created

四、MAT工具使用

启动后可以通过顶部菜单的 File->Open Heap Dump... 来打开一个快照文件,也可以在welcome 界面中点击 Open a Heap Dump。如果你的快照文件特别大,需要调整jvm参数,在 windows 下修改 MemoryAnalyzer.ini 文件,把 -Xmx 参数的值设置成适合的值(默认是1024M)。

在Overview选择卡中,可以选择需要分析的内容。比如 Leak Suspects 分析可能的内存泄漏,Histogram 查看每个类的实例统计。