简介
Arthas 官网地址(https://arthas.aliyun.com/en-us/) Arthas Github (https://github.com/alibaba/arthas)
谢谢阿里有提供一个这么好用的调试工具,记得很久以前写Asp.Net 的时候未了线上调试,用到花生壳转发映射到本地或者直接在服务器安装VS调试等
基础命令
cat
打印文件内容,和linux里的cat命令类似。
cat [文件路径]
cls
清空当前屏幕区域
echo
打印参数,和linux里的echo命令类似。
echo [参数]
base64
base64编码转换,和linux里的 base64 命令类似。
# 对文本内容base64编码base64 /tmp/test.txt# 对文本内容base64编码后输出base64 --input /tmp/test.txt --output /tmp/result.txt# 对文本文件解码base64 -d /tmp/result.txt# 用 base64 解码文件并保存结果到文件里base64 -d /tmp/result.txt --output /tmp/bbb.txt
tee
类似传统的tee命令, 用于读取标准输入的数据,并将其内容输出成文件。
tee [文件路径]# 将会把输入的内容输出到文件
pwd
返回当前的工作目录,和linux命令类似
pwd
reset
重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端stop时会重置所有增强过的类
# 还原指定类trace Test test# 还原所有类trace
version
输出当前目标 Java 进程所加载的 Arthas 版本号
history
打印命令历史
quit
退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
stop
关闭 Arthas 服务端,所有 Arthas 客户端全部退出
身份认证
auth
session
高级命令
dashboard
线程参数
- ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应。
- NAME: 线程名
- GROUP: 线程组名
- PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
- STATE: 线程的状态
- CPU%: 线程的cpu使用率。比如采样间隔1000ms,某个线程的增量cpu时间为100ms,则cpu使用率=100/1000=10%
- DELTA_TIME: 上次采样之后线程运行增量CPU时间,数据格式为秒
- TIME: 线程运行总CPU时间,数据格式为分:秒
- INTERRUPTED: 线程当前的中断位状态
- DAEMON: 是否是daemon线程
JVM 内部线程
Java 8之后支持获取JVM内部线程CPU时间,这些线程只有名称和CPU时间,没有ID及状态等信息(显示ID为-1)。 通过内部线程可以观测到JVM活动,如GC、JIT编译等占用CPU情况,方便了解JVM整体运行状况。
- 当JVM 堆(heap)/元数据(metaspace)空间不足或OOM时,可以看到GC线程的CPU占用率明显高于其他的线程。
- 当执行trace/watch/tt/redefine等命令后,可以看到JIT线程活动变得更频繁。因为JVM热更新class字节码时清除了此class相关的JIT编译结果,需要重新编译。
thread

- ID: 线程ID
- NAME: 线程名称
- GROUP: 线程分组
- PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
- STATE: 线程的状态
- CPU%: 线程的cpu使用率。比如采样间隔1000ms,某个线程的增量cpu时间为100ms,则cpu使用率=100/1000=10%
- DELTA_TIME: 上次采样之后线程运行增量CPU时间,数据格式为秒
- TIME: 线程运行总CPU时间,数据格式为分:秒
- INTERRUPTED: 线程当前的中断位状态
- DAEMON: 是否是daemon线程
# 线程预览thread# 查看指定线程 输出线程堆栈信息thread [线程ID]# 查看阻塞的线程thread -b# 指定cpu使用率统计的采样间隔,单位为毫秒,默认值为200thread -i [毫秒数]# 显示全部线程thread --all# 查看指定状态的线程thread –state [WAITING|RUNNABLE|TIMED_WAI]
jvm
输出JVM 信息
重要参数说明
THREAD相关
- COUNT: JVM当前活跃的线程数
- DAEMON-COUNT: JVM当前活跃的守护线程数
- PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数
- STARTED-COUNT: 从JVM启动开始总共启动过的线程次数
-
文件描述符相关
MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数
- OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数
查询参数
# 搜索属性jvm | grep [关键词]
sysprop
查看(修改)当前JVM的系统属性
SystemProperty

# 查看全部系统属性sysprop# 查看单个系统属性sysprop [属性名称]# 例sysprop user.country# 修改系统属性sysprop [属性名称] [属性值]# 例sysprop user.country [修改值]
sysenv
查看当前JVM的环境属性
SystemEnvironmentVariables
# 查看当前环境变量sysenv
vmoption
perfcounter
logger
查看logger信息,更新Logger Level
mbean
sc
“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d]、[E]、[f] 和 [x:]。

# 模糊搜索sc com.*# 打印类的详细信息, Tab 会有智能提示sc -d [包]# 打印类的详细信息 以及字段sc -d -f [包]# 打印类的详细信息 以及字段的深度sc [包] -d -f -x [深度]
sm
“Search-Method” 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。

# 输出类方法信息sm [包]# 输出类方法详细信息sm -d [包]
dump
dump 已加载类的 bytecode 到特定目录

# 将类的class 输出dump [类路径] [输出路径(选填)]# 例dump java.lang.String [-d [路径]]
heapdump
dump java heap, 类似jmap命令的heap dump功能
# dump到指定文件heapdump /tmp/dump.hprof# dump live对象heapdump --live /tmp/dump.hpro# 默认输出heapdump
vmtool
vmtool 利用JVMTI接口,实现查询内存对象,强制GC等功能。
指定 classloader name
# --limit参数,可以限制返回值数量,避免获取超大数据时对JVM造成压力。默认值是10vmtool --action getInstances --className java.lang.String --limit 10
指定 classloader hash
# 查看hashsc -d org.springframework.context.ApplicationContext# vmtool -c [HASH]# 例vmtool --action getInstances -c 19469ea2 --className org.springframework.context.ApplicationContext
指定返回结果展开层数
# vmtool -x [层数]# 例vmtool --action getInstances -c 19469ea2 --className org.springframework.context.ApplicationContext -x 2
执行表达式
vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext --express 'instances[0].getBeanDefinitionNames()'
强制GC
vmtool --action forceGc
jad
反编译指定已加载类的源码

# 查看源代码jad [类路径]# 例 包含ClassLoaderjad java.lang.String# 仅输出源代码不包含ClassLoaderjad com.xxscloud.mes.Application --source-only# 反编译方法jad com.xxscloud.mes.Application main --source-only# 反编译时不显示行号jad com.xxscloud.mes.Application --source-only --lineNumber false
classloader
查看classloader的继承树,urls,类加载信息
基础用法
# 基本信息classloader# 查看统计信息classloader -l# 查看继承树classloader -t
查看URLClassLoader实际的urls
classloader -c [HASH]
使用ClassLoader去查找resource
classloader -c [HASH] -r [资源路径]
使用ClassLoader去加载类
classloader -c [Hash] --load [类路径]# 例classloader -c 3d4eac69 --load demo.MathGame
monitor
watch
trace
tt
回顾问题
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况? 有什么办法可以监控到JVM的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从JVM内查找某个类的实例?
