锋利的开罐器-Arthas
官网:https://arthas.aliyun.com/
github:https://github.com/alibaba/arthas
做什么的?
Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
具体的引用场景
- CPU飙高,什么原因造成的?
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到 JVM 的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从 JVM 内查找某个类的实例?
- base64 - base64 编码转换,和 linux 里的 base64 命令类似
[arthas@70070]$ echo 'abc' > /tmp/test.txt
[arthas@70070]$ cat /tmp/test.txt
abc
[arthas@70070]$ base64 /tmp/test.txt
YWJjCg==
基础命令
- cat - 打印文件内容,和 linux 里的 cat 命令类似
- cls - 清空当前屏幕区域
- echo - 打印参数,和 linux 里的 echo 命令类似
- grep - 匹配查找,和 linux 里的 grep 命令类似
- help - 查看命令帮助信息
- history - 打印命令历史
- pwd - 返回当前的工作目录,和 linux 命令类似
- reset - 重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
- session - 查看当前会话的信息
[arthas@19836]$ session
Name Value
--------------------------------------------------
JAVA_PID 19836
SESSION_ID d864f3f9-a139-473d-951c-0fa8039ea901
- quit - 退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
- stop - 关闭 Arthas 服务端,所有 Arthas 客户端全部退出
- tee - 复制标准输入到标准输出和指定的文件,和 linux 里的 tee 命令类似
- version - 输出当前目标 Java 进程所加载的 Arthas 版本号
- - keymap - Arthas 快捷键列表及自定义快捷键
JVM相关命令
- dashboard - 当前系统的实时数据面板🔥
- thread - 查看当前 JVM 的线程堆栈信息🔥
- jvm - 查看当前 JVM 的信息🔥
- sysprop - 查看和修改 JVM 的系统属性
- sysenv - 查看 JVM 的环境变量
- vmoption - 查看和修改 JVM 里诊断相关的 option
- getstatic - 查看类的静态属性
- ognl - 执行 ognl 表达式
ognl '@java.lang.System@out.print("wangzijian")'
[arthas@19836]$ ognl '@demo.MathGame@random'
@Random[
serialVersionUID=@Long[3905348978240129619],
seed=@AtomicLong[7988179685469],
multiplier=@Long[25214903917],
addend=@Long[11],
mask=@Long[281474976710655],
DOUBLE_UNIT=@Double[1.1102230246251565E-16],
BadBound=@String[bound must be positive],
BadRange=@String[bound must be greater than origin],
BadSize=@String[size must be non-negative],
seedUniquifier=@AtomicLong[199880078823418412],
nextNextGaussian=@Double[0.0],
haveNextNextGaussian=@Boolean[false],
serialPersistentFields=@ObjectStreamField[][isEmpty=false;size=3],
unsafe=@Unsafe[sun.misc.Unsafe@64911ac2],
seedOffset=@Long[24],
]
- heapdump - dump java heap, 类似 jmap 命令的 heap dump 功能
- logger - 查看和修改 logger
- mbean - 查看 Mbean 的信息
- memory - 查看 JVM 的内存信息
- perfcounter - 查看当前 JVM 的 Perf Counter 信息
- vmtool - 从 jvm 里查询对象,执行 forceGc
Class、ClassLoader相关命令
- sc(Search Class) - 查看 JVM 已加载的类信息
[arthas@19836]$ sc demo.MathGame -d
class-info demo.MathGame
code-source /D:/arthas/math-game.jar
name demo.MathGame
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name MathGame
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-sun.misc.Launcher$AppClassLoader@5c647e05
+-sun.misc.Launcher$ExtClassLoader@28d93b30
classLoaderHash 5c647e05
- sm(Search Method) - 查看已加载类的方法信息
[arthas@19836]$ sm java.lang.Integer
java.lang.Integer <init>(I)V
java.lang.Integer <init>(Ljava/lang/String;)V
java.lang.Integer numberOfLeadingZeros(I)I
java.lang.Integer numberOfTrailingZeros(I)I
java.lang.Integer bitCount(I)I
java.lang.Integer equals(Ljava/lang/Object;)Z
java.lang.Integer toString(II)Ljava/lang/String;
java.lang.Integer toString()Ljava/lang/String;
java.lang.Integer toString(I)Ljava/lang/String;
java.lang.Integer hashCode(I)I
java.lang.Integer hashCode()I
java.lang.Integer min(II)I
java.lang.Integer max(II)I
- jad - 反编译指定已加载类的源码🔥
[arthas@19836]$ jad demo.MathGame print
ClassLoader:
+-sun.misc.Launcher$AppClassLoader@5c647e05
+-sun.misc.Launcher$ExtClassLoader@28d93b30
Location:
/D:/arthas/math-game.jar
public static void print(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer(number + "=");
/*34*/ for (int factor : primeFactors) {
/*35*/ sb.append(factor).append('*');
}
/*37*/ if (sb.charAt(sb.length() - 1) == '*') {
/*38*/ sb.deleteCharAt(sb.length() - 1);
}
/*40*/ System.out.println(sb);
}
Affect(row-cnt:1) cost in 97 ms.
- mc - 内存编译器,内存编译.java
文件为.class
文件
- redefine - 加载外部的.class
文件,redefine 到 JVM 里🔥❗
- classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource
- dump - dump 已加载类的 byte code 到特定目录
- retransform - 加载外部的.class
文件,retransform 到 JVM 里
http://zjyun.cc/wordpress/2809435016662