常用故障诊断工具介绍
JDK自带命令行工具
MAT
即Memory Analyzer Tool,是eclipse提供的一个java内存分析工具,下载链接
使用MAT工具前,需要使用JDK命令jmap -dump生成内存dump文件,再通过MAT工具打开dump文件即可进行分析。由于dump文件通常较大,建议使用专用服务器进行分析,通过MemoryAnalyzer.ini文件可以调整MAT工具的运行内存。
UI介绍

常用功能菜单:
- Unreachable Objects Histogram:不可达对象直方图,也就是可以被回收的对象
- Histogram :列出每个类的对象实例数和占用内存大小
- Dominator Tree 支配节点树:列出最大的对象并按照大小排序,可以很方便定位出大对象下的哪个字段占用内存最多
- Top Consumers:按包和类统计大对象的占用情况
- Duplicate Classes:检测同一个类被多个类加载器加载的情况
- Leak Suspects:分析可能存在的内存泄露问题,其实跟Dominator Tree的分析结果差不多
- Thread Overview:这个菜单不太显眼,可以查看线程栈帧、线程名等信息
- 属性区 : 在界面左侧,选中某个对象则可以查看对象的属性
点击功能菜单,对菜单内的一些表单字段说明:
- Shallow Heap:指该对象在没有引用其他对象的情况下本身占用内存大小,对于数组对象则表示所有元素所占的内存大小总和
- Retained Heap:包含对象本身的大小和引用的其他对象的大小,即对象被回收时应释放的内存大小(但还需排除掉被GC Root引用的对象)
- Percentage:占整个堆内存的比例
右键一个具体对象,展开子菜单:
- list objects - with outgoing references : 查看这个对象持有的外部对象引用,可用于查看这个对象的内部详情,与属性区的区别是这个功能只能查看对象引用及其占用的内存大小,而属性区可以查看对象引用和基本类型字段的值。
- list objects - with incoming references : 查看这个对象被哪些外部对象引用,可用于追踪引用链。
- show objects by class - with outgoing references :查看这个对象类型持有的外部对象引用
- show objects by class - with incoming references :查看这个对象类型被哪些外部对象引用
- Path To GC Roots : 用于分析引用链,追踪到GC Roots,用于分析对象没有被垃圾回收的原因
MAT中最常用的功能(就本人使用情况来看)应该是:
- 使用Dominator Tree分析潜在的内存泄露,使用Leak Suspects也可以,结果是一样的
- 使用Path To GC Roots分析对象没有被垃圾回收的原因
- 使用属性区或list objects - with outgoing references查看对象的内部信息
- 查看Thread Overview,可以通过线程名过滤查看线程栈帧(可与jstack的结果配合使用)
arthas
Arthas是Alibaba开源的Java诊断工具,需要先下载安装,并使用命令行的方式交互。
详细的手册在官网已经提供,或者使用help命令来查询,这里只列出常用用法
类加载器
classloader -t 用于查看ClassLoader继承树,在多ClassLoader的应用中非常有用
classloader -c <loader id> 查看ClassLoader中包含的url
classloader -c <loader id> -r java/lang/String.class 用于在ClassLoader下查找是否存在class文件,也可以用于查找资源文件
类
sc <class name> 搜索jvm中是否存在这个类(必须已经加载),支持模糊搜索,支持.和/作为分隔符
sc -d -f <class name> 打印类的详细信息和字段信息
反编译
jad java.lang.String [-c <loader id>] 当一些类是通过动态代理生成的,这个功能就比较有用,也可用于查看补丁是否生效
查看运行时参数
sysprop 系统参数
sysenv 环境变量
vmoption jvm参数
jvm jvm信息
实时监控
dashboard
线程
thread 查看线程状态
thread -n 3 找出最忙的前3个线程并打印堆栈
thread -b 找出阻塞其他线程的线程
ognl
ognl [-c <classloader>] <express> 使用ognl表达式可以直接与应用交互,最常用的是可以读取某个类的静态字段或通过spring上下文读取bean的字段值,详见ognl官方手册
ognl '@com.xxx.SpringContextUtil@getApplicationContext().getBean("xxx")' 通过工具类获取Spring上下文,进而读取bean的字段值
GCeasy
GCeasy是一款在线的GC日志分析工具
SpringBoot Actuator
// TODO