获取堆转储快照
如何获取堆转储快照?常用的有两种方式:
JVM启动时增加参数
出现OOM时生成堆dump:
-XX:+HeapDumpOnOutOfMemoryError
指定生成的dump文件路径,不指定就在当前路径:
-XX:HeapDumpPath=/home/heap.hprof
示例:
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof -jar -Xms256m -Xmx256m test.jar &
通过jmap指令生成
在程序运行时执行指令,直接生成当前JVM的dump文件:
jmap -dump:format=b,file=/tmp/heap.hprof vmid
vmid通常就是pid(进程ID)
分析堆转储快照
Eclipse Memory Analyzer
简介
Eclipse Memory Analyzer可以分析堆转储快照。这个工具分为Eclipse插件版和独立版两种,如果你是使用Eclipse作为开发工具,那么可以使用插件版MAT,非常方便。
- Retained Heap表示这个对象以及它所持有的其它引用(包括直接和间接)所占的总内存。
- Shallow Heap就是当前对象自己所占内存的大小,不包含引用关系的。
- Percentage就是它所占总内存的百分比。
- 类名左下角那个小圆点表明该对象是GC Root。
示例
代码如下:
运行代码,使用jmap指令dump出堆转储快照,然后用Eclipse Memory Analyzer进行分析。可以看到Strong、Soft、Weak三个类里的大字节数组。
对于Strong类里的字节数组,我们查看它到GC Roots的路径,这里选择排除软引用和弱引用。
可以看到它到GC Roots是可达的。
再看虚引用里的字节数组,查看它到GC Roots的路径,同样选择排除软引用和弱引用。
发现它到GC Roots是不可达的,到GC Roots不可达意味着垃圾收集时会被清理掉,所以如果发生了OOM,那罪魁祸首肯定不是它。