如何排查内存泄漏
使用MAT工具排查内存泄漏的问题
一.概要说明
使用 Memory Analyzer 来分析生产环境的 Java 堆转储文件,可以从数以百万计的对象中快速计算出对象的 Retained Size,查看是谁在阻止垃圾回收,并自动生成一个 Leak Suspect(内存泄露可疑点)报表。
备注:Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用
Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的
二.操作步骤
1.初步判定是否存在内存泄漏问题,压测前后内存空间是否释放。使用命令:free –h
2.若存在内存泄漏,使用命令:jmap -dump:live,format=b,file=heap.hrof <pid>。
pid是JVM进程的id,
heap.hrof
是生成的文件名称,在执行命令的目录下面。
备注:在JVM的配置参数中可以添加 -XX:+HeapDumpOnOutOfMemoryError 参数,当应用抛OutOfMemoryError 时自动生成dump文件。
3.使用MAT工具打开heap文件。
4.打开工具后,重点关注几个选项:
备注:点击Details进入详情页面。在详情页面Shortest Paths To the Accumulation Point表示GC root到内存消耗聚集点的最短路径,如果某个内存消耗聚集点有路径到达GC root,则该内存消耗聚集点不会被当做垃圾被回收。
备注:Class Name : 类名称,java类名
Objects : 类的对象的数量,这个对象被创建了多少个
Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用
Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的
补充:
为了找到内存泄露,获取了两个堆转储文件,两个文件获取时间间隔是一天(因为内存只是小幅度增长,短时间很难发现问题)。对比两个文件的对象,通过对比后的结果可以很方便定位内存泄露。
MAT同时打开两个堆转储文件,分别打开Histogram,选择Group By package,然后对比各对象的变化。
三.总结
MAT可以用它来分析内存问题,也可以用来监控整个 Java 应用程序的状态和行为。通过读取应用程序运行时由 Java 运行时环境生成的转储文件快照,Memory Analyzer 使您能够分析那些调试代码可能无法发现的复杂问题。