一、什么是Arthas
官方介绍:Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到JVM的实时运行状态?
怎么快速定位应用的热点,生成火焰图?
二、如何下载
下载地址:https://github.com/alibaba/arthas/releases
三、如何使用
可以直接执行命令,选择需要attach的java进程回车
java -jar arthas-boot.jar
在执行该命令时可能发生异常,这里记录几点我遇到的问题
1.选择了java进程回车后报错
[ERROR] Start arthas failed, exception stack trace:
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
at sun.tools.attach.LinuxVirtualMachine.(LinuxVirtualMachine.java:106)
at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:78)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:250)
at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:85)
at com.taobao.arthas.core.Arthas.(Arthas.java:28)
at com.taobao.arthas.core.Arthas.main(Arthas.java:123)
解决:在对应JAVA进程启动时添加JVM参数 -XX:+StartAttachListener
2.选择了java进程回车后报错
[ERROR] Start arthas failed, exception stack trace:
java.io.IOException: well-known file /tmp/.java_pid87449 is not secure: file should be owned by the current user (which is 0) but is owned by 30001
at sun.tools.attach.LinuxVirtualMachine.checkPermissions(Native Method)
at sun.tools.attach.LinuxVirtualMachine.(LinuxVirtualMachine.java:117)
at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:78)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:250)
at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:85)
at com.taobao.arthas.core.Arthas.(Arthas.java:28)
at com.taobao.arthas.core.Arthas.main(Arthas.java:123)
[ERROR] attach fail, targetPid: 87449
该问题发生的原因是执行该程序的用户需要和目标进程具有相同的权限。
四、常用命令
- dashboard
$ dashboard
ID NAME GROUP PRIORI STATE %CPU TIME INTERRU DAEMON
17 pool-2-thread-1 system 5 WAITIN 67 0:0 false false
27 Timer-for-arthas-dashb system 10 RUNNAB 32 0:0 false true
11 AsyncAppender-Worker-a system 9 WAITIN 0 0:0 false true
9 Attach Listener system 9 RUNNAB 0 0:0 false true
3 Finalizer system 8 WAITIN 0 0:0 false true
2 Reference Handler system 10 WAITIN 0 0:0 false true
4 Signal Dispatcher system 9 RUNNAB 0 0:0 false true
26 as-command-execute-dae system 10 TIMED_ 0 0:0 false true
13 job-timeout system 9 TIMED_ 0 0:0 false true
1 main main 5 TIMED_ 0 0:0 false false
14 nioEventLoopGroup-2-1 system 10 RUNNAB 0 0:0 false false
18 nioEventLoopGroup-2-2 system 10 RUNNAB 0 0:0 false false
23 nioEventLoopGroup-2-3 system 10 RUNNAB 0 0:0 false false
15 nioEventLoopGroup-3-1 system 10 RUNNAB 0 0:0 false false
Memory used total max usage GC
heap 32M 155M 1820M 1.77% gc.ps_scavenge.count 4
ps_eden_space 14M 65M 672M 2.21% gc.ps_scavenge.time(m 166
ps_survivor_space 4M 5M 5M s)
ps_old_gen 12M 85M 1365M 0.91% gc.ps_marksweep.count 0
nonheap 20M 23M -1 gc.ps_marksweep.time( 0
code_cache 3M 5M 240M 1.32% ms)
Runtime
os.name Mac OS X
os.version 10.13.4
java.version 1.8.0_162
java.home /Library/Java/JavaVir
tualMachines/jdk1.8.0
_162.jdk/Contents/Hom
e/jre
通过该仪表盘我们可以获取到:
1.对应进程中线程信息,可以直观看到哪些线程占用的CPU较高
2.JVM内存使用情况,包括年轻带(伊甸区,存活区),老年带,元空间(非堆)的GC情况
- thread
查看当前线程信息,查看线程的堆栈
命令:thread -n 3 ->打印当前最忙的top3线程
- monitor
方法执行监控,可以实时监控某个方法的执行耗时
$ monitor -c 5 demo.MathGame primeFactors
- trace
方法内部调用路径,并输出方法路径上的每个节点上耗时,可以直接根据执行时间进行过滤
$ trace demo.MathGame run '#cost > 10'
- stack
输出当前方法被调用的调用路径,可以直接根据执行时间进行过滤
$ stack demo.MathGame primeFactors '#cost>5'
- jad
将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻.
命令:jad xx.xx.xx.ClassA
当存在多个源码时,可以通过-c 指定classLoad
- jvm
查看当前JVM信息
通过此命令可以直接获取当前死锁的线程数,JVM当前活跃的线程数等
- vmoption
查看,更新VM诊断相关的参数
- ognl
执行ognl表达式,可以查看类的静态属性、执行类的静态函数等等,例如
$ ognl '@[email protected]("hello")'
$ ognl '@demo.MathGame@random'
同理,如若存在多个相同类路径代码,则使用-c参数指定classload
- sc
查看JVM已加载的类信息,可以打印类的详细信息,打印出类的Field信息等
- heapdump
dump java heap, 类似jmap命令的heap dump功能。
heapdump /tmp/dump.hprof
heapdump --live /tmp/dump.hprof
五、进阶使用
- 火焰图
六、参考文档
https://alibaba.github.io/arthas/quick-start.html