概述
在生产环境中,有时会遇到项目报 OOM 的错误,如果能知道是什么对象导致的,就能提高我们解决该问题的几率。这里,MAT就是分析 JVM 堆内存的常用工具之一。
创建dump文件
- 方式一:使用 jmap 命令创建,例如 jmap -dump:format=b,file=heapdump.hprof 27012(进程ID)
- 方式二:运行java程序的时候开启HeapDumpOnOutOfMemoryError参数(发生OOM的时候自动创建dump),例如 java -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError HelloWorld
分析dump文件
MAT工具下载地址:https://www.eclipse.org/mat/downloads.php
1.运行 MemoryAnalyzer.exe,点击 Open a Heap Dump,选择上一步生成的 dump 文件
2.分析堆内存
如图所示,提示当前有个数组对象,占用 88.67% 的堆空间
点击下面的 Details
链接,会跳转到当前问题的详细界面。
如下图所示,可以很清楚的看出 TestA 对象占用了大量的内存,这样就可以针对性地排查代码
3.Shallow Heap 和 Retained Heap
Shallow Heap:对象自身占用的内存大小,不包括它引用的对象。
Retained Size:当前对象的Shallow Heap + 当前对象直接或间接引用的对象总和,其中要排除被GC Roots引用的对象。等价于GC后能从堆内存释放的空间大小。
如上图所示:
A 对象的 Retained Heap = A 对象的 Shallow Heap
B 对象的 Retained Heap = B 对象的 Shallow Heap + C 对象的 Shallow Heap
这里 B 对象的 Retained Heap 不包含 D 对象,因为 D 对象被GC Roots直接引用
换一种情况:
如上图所示,D 对象不再被 GC Roots 直接引用,所以
B 对象的 Retained Heap = B 对象的 Shallow Heap + C 对象的 Shallow Heap + D 对象的 Shallow Heap