阿里内部的那个牛逼带闪电的Java诊断工具终于开源了( 二 )

4. 通过sysenv命令来获取到进程的Main Class
$ sysenv | grep MAINJAVA_MAIN_CLASS_71560 demo.MathGame5. 通过jad来反编绎Main Class
$ jad demo.MathGameClassLoader:+-sun.misc.Launcher$AppClassLoader@3d4eac69+-sun.misc.Launcher$ExtClassLoader@66350f69Location:/tmp/arthas-demo.jar/** Decompiled with CFR 0_132.*/package demo;import java.io.PrintStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Random;import java.util.concurrent.TimeUnit;public class MathGame {private static Random random = new Random;private int illegalArgumentCount = 0;public static void main(String[] args) throws InterruptedException {MathGame game = new MathGame;do {game.run;TimeUnit.SECONDS.sleep(1L);} while (true);}public void run throws InterruptedException {try {int number = random.nextInt;List<Integer> primeFactors = this.primeFactors(number);MathGame.print(number, primeFactors);}catch (Exception e) {System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage);}}public static void print(int number, List<Integer> primeFactors) {StringBuffer sb = new StringBuffer("" + number + "=");Iterator<Integer> iterator = primeFactors.iterator;while (iterator.hasNext) {int factor = iterator.next;sb.append(factor).append('*');}if (sb.charAt(sb.length - 1) == '*') {sb.deleteCharAt(sb.length - 1);}System.out.println(sb);}public List<Integer> primeFactors(int number) {if (number < 2) {++this.illegalArgumentCount;throw new IllegalArgumentException("number is: " + number + ", need >= 2");}ArrayList<Integer> result = new ArrayList<Integer>;int i = 2;while (i <= number) {if (number % i == 0) {result.add(i);number /= i;i = 2;continue;}++i;}return result;}}Affect(row-cnt:1) cost in 970 ms.6. watch
通过watch命令来查看demo.MathGame#primeFactors函数的返回值:
$ watch demo.MathGame primeFactors returnObjPress Ctrl+C to abort.Affect(class-cnt:1 , method-cnt:1) cost in 107 ms.ts=2018-11-28 19:22:30; [cost=1.715367ms] result=ts=2018-11-28 19:22:31; [cost=0.185203ms] result=ts=2018-11-28 19:22:32; [cost=19.012416ms] result=@ArrayList[@Integer[5],@Integer[47],@Integer[2675531],]ts=2018-11-28 19:22:33; [cost=0.311395ms] result=@ArrayList[@Integer[2],@Integer[5],@Integer[317],@Integer[503],@Integer[887],]ts=2018-11-28 19:22:34; [cost=10.136007ms] result=@ArrayList[@Integer[2],@Integer[2],@Integer[3],@Integer[3],@Integer[31],@Integer[717593],]ts=2018-11-28 19:22:35; [cost=29.969732ms] result=@ArrayList[@Integer[5],@Integer[29],@Integer[7651739],]5. 退出arthas
如果只是退出当前的连接,可以用quit或者exit命令 。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上 。
如果想完全退出arthas,可以执行shutdown命令 。
 
常用命令基础命令

  • help——查看命令帮助信息
  • cls——清空当前屏幕区域
  • session——查看当前会话的信息
  • reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
  • version——输出当前目标 Java 进程所加载的 Arthas 版本号
  • quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
  • shutdown——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
  • keymap——Arthas快捷键列表及自定义快捷键
jvm相关
  • dashboard——当前系统的实时数据面板
  • thread——查看当前 JVM 的线程堆栈信息
  • jvm——查看当前 JVM 的信息
  • sysprop——查看和修改JVM的系统属性
  • New! getstatic——查看类的静态属性
class/classloader相关
  • sc——查看JVM已加载的类信息
  • sm——查看已加载类的方法信息
  • dump——dump 已加载类的 byte code 到特定目录
  • redefine——加载外部的.class文件,redefine到JVM里
  • jad——反编译指定已加载类的源码
  • classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource
monitor/watch/trace相关