前言
在看JVM性能调优和故障处理工具的时候JDK提供了一些比较好用的工具,比如说jps是一个用来监控虚拟机的进程状况的工具,jstat是一个虚拟机统计信息监视的工具,jinfo是一个Java配置信息工具,jmap是一个Java内存映像工具,jstack是一个堆栈跟踪工具等等,这些工具都十分小巧实用。但是最近发现一个阿里开源的Java在线诊断工具Arthas(阿尔萨斯),可堪称诊断利器。官方文档是这么介绍的:
当你遇到以下类似问题而束手无策时,
Arthas可以帮助你解决:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
这么强大的功能,看起来就十分吸引人,赶紧学起来。
先放上官方的链接 Arthas用户文档
一些命令的使用在官方文档上都有详细的解释,这边个人觉得jad、mc、redefine这几个命令比较有意思,就简单记录一下。其实这几个命令也就是解决上面的2、3、4的问题。其中如何安装和启动Arthas就不赘述了,在官方文档里有详细的说明。
jad
jad能够反编译Class成Java文件。
1 | jad --source-only com.arthas.demo |
com.arthas.demo 是要反编译的Class
输出结果如下

有些时候为了方便看我们想要执行的代码是否执行到了,可以将Class反编译的Java文件另存到一个目录下面,再打开它。
1 | jad --source-only com.arthas.demo > ./demo.java |
mc
mc用来将Java源文件编译成class文件
1 | mc MathGame.java -d ./ |
redefine
redefine是用来加载外部的class文件,用redefine修改掉JVM方法区中对应的class,能够在不重新发布的情况下修改掉程序或者增添日志。即实现热更新。
一般是这么使用的,这边举例说明。首先定义这么一个类。
1 | package com.arthas; |
将其打包成jar包,我这边用assembly打包方式,其中pom.xml,具体的方式可百度解决。
1 |
|
在resources下新建一个assembly.xml文件
1 |
|
将工程打成jar包放在服务器上执行。

接下来我们简单修改函数中的内容
1 | public void PrintOneLine(){ |
重新编译这个java文件成class文件。
启动Arthas,使用redefine命令。
1 | redefine demo.class |
重定义成功,看一下运行着的项目成功的修改掉了代码中的内容。

总结
一般来说,jad、mc、redefine三个命令在线上是一起使用的,具体的步骤是第一步:用jad命令反编译出你想要的的那个类的Java文件,接着可以直接用vim对Java中的文件进行修改。第二步:用mc命令重新编译Java文件成class文件。由于有些时候mc的时候会有问题,这时候也可以用javac手动编译。第三步:用redefine命令对想要修改的class文件进行修改。
但是,redefine也有一定的使用局限性,并不是可以任意使用。官方文档里这么描述
- 不允许新增加field/method
- 正在跑的函数,没有退出不能生效,比如下面新增加的
System.out.println,只有run()函数里的会生效
1 | public class MathGame { |