MAT的官网在: www.eclipse.org/mat/ ,可以看下它的介绍——MAT是一款高性能、具备丰富功能的Java堆内存分析工具,可以用来排查内存泄漏和内存浪费的问题。
基础概念
Heap Dump
Heap Dump是Java进程在某个时刻的内存快照,不同JVM的实现的Heap Dump的文件格式可能不同,进而存储的数据也可能不同,但是一般来说。
Heap Dump中主要包含当生成快照时堆中的java对象和类的信息,主要分为如下几类:
- 对象信息:类名、属性、基础类型和引用类型
- 类信息:类加载器、类名称、超类、静态属性
- gc roots:JVM中的一个定义,进行垃圾收集时,要遍历可达对象的起点节点的集合
- 线程栈和局部变量:快照生成时候的线程调用栈,和每个栈上的局部变量
Heap Dump中没有包含对象的分配信息,因此它不能用来分析这种问题:一个对象什么时候被创建、一个对象时被谁创建的。
Shallow vs. Retained Heap
解释1:
Shallow Heap(浅堆) 表示该对象自身占用的堆内存,不包括它引用的对象。针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。
Retained Heap(深堆) 表示当前对象大小+当前对象可直接或间接引用到的对象的大小总和。换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。
解释2:
Shallow heap 是一个对象本身占用的堆内存大小。一个对象中,每个引用占用8或64位,Integer占用4字节,Long占用8字节等等。
Retained heap ,对象X的Retained heap指的时候它的Retained set中的所有对象的Shallow si的和,换句话说,Retained heap指的是对象X的保留内存大小,即由于它的存活导致多大的内存也没有被回收。
Dominator Tree
MAT根据堆上的对象引用关系构建了支配树(Dominator Tree),通过支配树可以很方便得识别出哪些对象占用了大量的内存,并可以看到它们之间的依赖关系。
MAT安装
- 工具下载地址:www.eclipse.org/mat/downloa…
- 下载后,修改./mat.app/Contents/Eclipse目录下的配置文件MemoryAnalyzer.ini,修改其中的-Xms和-Xmx两个参数,设置为比dump文件大的某个值
- 启动mat,菜单栏找到"Eclipse Memory Analyzer" -> "Preferences" -> "Memory Analyzer" ,勾选"Keep unreachable objects"
- 菜单栏 "File" -> "Open Heap Dump",打开dump文件,打开后如下图:
可以使用"Histogram"、"Dominator Tree"、"Leak Suspects"等做下分析,常见问题很容易排查出来
服务分析示例:
红框内,对象属于日志,可以优化或降低日志等级,来解决对象过大, 。