MAT内存分析Dump文件
前面我们讲解了MAT内存分析工具,如何在JDK8的情况下启动成功,今天我们主要讲解下,如何使用MAT来分析内存Dump堆栈快照文件,便于我们在遇到OOM情况下,能够快速的定位到内存溢出或者内存泄漏的问题
1.MAT工具使用
MAT不是一个万能工具,它并不能处理所有类型的堆存储文件。但是大部分的文件我们都可以处理,在分析Dump文件之前,我们首先了解,为什么会出现OOM(OutOfMemoryError)
通常来说,出现OOM问题的原因,分为以下2种:
-
内存泄露,JVM内存中的对象已经死了,没有任何可达路径及引用,但是对象没有被回收,GC线程没有清理掉这部分垃圾对象
此刻我们必须通过工具通过找出对象未被回收的原因, 定位泄露的代码位置,解决问题
-
内存溢出,内存中的对象都还必须存活着,但是 JVM堆的 空间不够,空间无法给新的对象分配地址, 有可能是正常业务,你的堆栈设置较小,业务量比较大就会出现这种问题
此刻,我们要检查JVM设置, 检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长,存活周期过长、检查对象持有状态时间过长的情况, 避免出现这种大对象长时间持有的场景。
1.1 程序启动,Dump堆栈快照
我们依旧采用SpringBoot项目 启动, 然后配置Controller
通过模拟Http请求,设置JVM参数100M,然后通过 50次并发量 来增加内存,造成内存OOM,生成Dump文件
@GetMapping("/test")
private String test(Integer num) {
try {
byte[] b = null;
for (int i = 1; i <= num; i++) {
//设置 2M的对象
log.info("======== " + i + "次添加2M对象");
b = new byte[2 * 1024 * 1024];
Thread.sleep(3000);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return "success";
}
1.2 启动MAT内存分析工具
下面我们直接启动MAT内存分析工具
然后选择自己的快照文件, Open a Heap Dump 打开快照文件
选择默认的 Leak Suspects Report(内存泄露怀疑分析报告)->选择Finish
点击 Finish 完成
2.MAT分析Dump文件
打开Dump文件后,我们看到的是下面的界面,是一个饼状图,我们看下饼状图到底有什么意思,展示的Problem suspect 和Reminder到底是什么意思
- Leak Suspects 内存泄漏分析
- System Overview 系统概览信息
- OverView 饼状图,显示堆内存 Total 68.2M 堆一共68M
- Problem Suspect 1 内存泄漏排查点, 有可能发生内存泄漏的地方,内存大小占用 58.1M
- Remainder 内存正常的地方
下面我们来看下System Overview, 后面会逐个分析 Problem Suspect 1 内存泄漏排查点1, 及 Over概览信息, 本文我们主要讲解 System Overview 系统概览信息,看下有哪些信息
3.System Overview 系统概览信息
点击System Overview 可以看到以下信息,有时候从这里就可以直接定位到问题
- Heap Dump Overview 堆栈Dump文件快照的概览信息
- System Properties 系统变量属性信息
- Thread Overview 线程概览信息
- Top Consumers 通过图形列出最大的大对象Object 信息,内层又分为 Biggest Objects大对象信息, Biggest Top Level Dominator Classes 挨个计算占用内存的都是什么东西,Biggest Top-Level Dominator Packages 比较大的包文件信息等
- Class Histogram 类的大对象信息
3.1 Heap Dump Overview 堆栈Dump文件快照的概览
系统概览信息 如下 System Overview
| 属性 | 信息 | 解释 |
|---|---|---|
| Used heap dump | 68.2 MB | 堆大小 68.2M |
| Number of objects | 156,800 | 对象数量 156800个 |
| Number of classes | 6,056 | Class类数量6056个 |
| Number of class loaders | 30 | class loaders 类加载器数量 30个 |
| Number of GC roots | 2,551 | GC root根节点2551 |
| Format | hprof | 堆栈保存格式 hprof |
| JVM version | 虚拟机格式 | |
| Time | GMT+8 23:49:46 | 时区信息 |
| Date | 2023年4月17日 | 时间信息 |
| Identifier size | 64-bit | 位数 |
| Compressed object pointers | true | 是否压缩 true |
| File path | C:\Users\jzj\Desktop\java_pid13952.hprof | hprof堆快照文件路径信息 |
| File length | 83,511,127 | hprof堆快照文件大小 |
3.2 System Properties 系统变量属性信息
点击 System Properties ,可以查看系统变量属性信息,我们比较熟知的信息都在里面,我们列举几个比较熟知的信息,如下
- file.encoding 文件编码格式 UTF-8
- java.class.path classpath配置信息
- java.home JDK安装路径信息
- java.io.tempdir java临时文件信息
- java.runtime.version java运行版本System Properties 1.8.0_181-b13
3.3 Thread Overview 线程概览信息
点击线程概览信息,我们可以看到线程的信息,包括线程名字,线程浅堆Shallow Heap及 深堆 Retained Heap等信息,介绍之前,我们介绍下Shallow Heap 和 Retained Heap
- Shallow Heap 浅堆
- 浅堆的意思是是说当前对象本身自身的大小(一个对象由对象头 和 该对象实例数据 及对象头对齐填充信息构成)
- Retained Heap 深堆
- 深堆是一种统计的结果,统计的就是该对象及对象引用信息,如果当前对象被回收了,那么它及它的引用在一起,可以一共回收掉多少内存
下面我们介绍下 线程概览信息
- Object / Stack Frame 线程堆栈信息
- org.apache.tomcat.util.threads.TaskThread @ 0xfa59de78
- Name 线程名字
- http-nio-8078-exec-11
- Shallow Heap 浅堆大小
- 128 浅堆大小128
- Retained Heap 深堆大小,能回收的内存
- 2,100,400 回收该对象 可以回收 2,100,400的内存空间
- Max. Locals' Retained Heap 最大本地深堆信息
- Context Class Loader class类加载器信息
- org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader @ 0xfa4b9d38
- Is Daemon 是否是守护线程
- true 是守护线程
- Priority 线程优先级
- 优先级 5
- State 线程状态
- alive, sleeping, waiting, waiting with timeout 活跃,休眠,等待等状态
- State value 状态值
- 0xe1 16进制的状态值
3.4 Top Consumers 通过图形列出最大的大对象Object 信息
Top Consumers 通过图形列出最大的大对象Object 信息,内层又分为 Biggest Objects大对象信息, Biggest Top Level Dominator Classes 挨个计算占用内存的都是什么东西,Biggest Top-Level Dominator Packages 比较大的包文件信息等,下面我们依次看下
Biggest Objects Overview 概览信息,也就是大对象信息饼状图
Biggest Objects 大对象具体信息,包括浅堆,深堆信息
Biggest Top Level Dominator Classes Overview概览 占用内存计算,可以看到每个对象的具体占用内存信息的饼状图
Biggest Top Level Dominator Classes 实际信息 ,包括数量, 占用内存大小, 深堆大小, 深堆占用的比例信息等
Biggest Top-Level Dominator Packages 比较大的包文件信息
3.5 Class Histogram 类的大对象信息
Class Histogram 类的大对象信息, 包括对象数量, 深堆大小,浅堆大小等
至此,本文使用MAT对OOM溢出的堆快照信息进行了分析,这次我们主要讲解了第一个System Overview系统概览信息,在这里主要是为了看到堆,对象,类,深堆,浅堆信息,首先我们的看懂MAT的这些信息,才能更好的分析定位内存溢出