调试排错 - Arthas使用

Arthas简介

Arthas是什么

Arthas 是 Alibaba 开源的 Java 诊断工具。支持 JDK6+, 采用命令行交互模式,提供 Tab 自动补全,可以方便定位和诊断线上程序的运行问题。

Arthas入门

Arthas安装

下载 arthas-boot.jar,然后用 java -jar 的方式启动:

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
1
2

Arthas能解决什么问题

使用 Arthas 可以帮助你解决:

  • 可以很方便查到一类是从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  • 怀疑自己的代码未被部署到服务器,可以通过命令快速验证服务器上的代码就是本地的代码;
  • 可以直接通过 arthas 进行线上 debug,查看方法返回值以确认问题所在;
  • 可以很方便嵌入自己的 debug 代码,快速验证猜想;
  • 操作完成后,可以将所有 debug 代码删除,从而避免影响线上运行;

常用命令

dashboard

dashboardopen in new window 命令可以查看当前系统的实时数据面板。

dashboard

面板中 Thread 各数据说明:

名称说明
IDJava级别的线程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内部线程包括下面几种:

  • JIT编译线程: 如 C1 CompilerThread0、 C2 CompilerThread0
  • GC线程: 如 GC Thread0、 G1 Young RemSet Sampling
  • 其它内部线程: 如 VM Periodic Task Thread,、VM Thread、 Service Thread

thread

threadopen in new window 命令可以查看当前 JVM 的线程堆栈信息。一目了然的了解系统的状态,哪些线程比较占cpu,他们到底在做什么。

thread 参数列表:

参数名称参数说明
id线程id
-n指定最忙的前N个线程并打印堆栈
[b]找出当前阻塞其他线程的线程
[i ]指定cpu占比统计的采样间隔,单位为毫秒
[--all]显示所有匹配的线程

例如:thread -n 3 展示当前最忙的前3个线程并打印堆栈

classloader

classloaderopen in new window 命令将 JVM 中所有的 classloader 的信息统计出来,并可以展示继承树,urls 等。了解当前系统中有多少类加载器,以及每个加载器加载的类数量,帮助您判断是否有类加载器泄露。

jad

jadopen in new window 命令可以对类进行反编译。将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑。

参数列表:

参数名称参数说明
class-pattern类名表达式匹配
[c:]类所属 ClassLoader 的 hashcode
[classLoaderClass:]指定执行表达式的 ClassLoader 的 class name
[E]开启正则表达式匹配,默认为通配符匹配

例如:jad java.lang.String toString

monitor

monitoropen in new window 监控某个特殊方法的调用统计数据,包括总调用次数,平均 rt,成功率等信息,每隔5秒输出一次。

watch

watchopen in new window 命令用于方法执行数据观测。可以观察指定方法的调用情况。能观察到的范围为:返回值抛出异常入参,通过编写 OGNL 表达式进行对应变量的查看。

参数列表:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
express观察表达式,主要由 ognl 表达式组成,默认值:{params, target, returnObj}
condition-express条件表达式
[b]方法调用之前观察
[e]方法异常之后观察
[s]方法返回之后观察
[f]方法结束之后(正常返回和异常返回)观察
[E]开启正则表达式匹配,默认为通配符匹配
[x:]指定输出结果的属性遍历深度,默认为 1

例子:watch demo.MathGame primeFactors "{params,throwExp}" -e 观察方法 demo.MathGame#primeFactors 执行的入参,仅当方法抛出异常时才输出

tt

ttopen in new window 命令是 Time Tunnel 缩写,方法执行数据的时空隧道,可以录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

退出arthas

如果只是退出当前的连接,可以用 quit 或者 exit 命令。Attach 到目标进程上的 arthas 还会继续运行,端口会保持开放,下次连接时可以直接连接上。

如果想完全退出 arthas,可以执行 stop 命令。

更多命令

实际场景

博客园 - yougeweopen in new window

查看最繁忙的线程,以及是否有阻塞情况发生?

thread -n 3 # 查看最繁忙的三个线程栈信息
thread  # 以直观的方式展现所有的线程情况
thread -b #找出当前阻塞其他线程的线程
1
2
3

参考资料