MAT内存分析工具 mat内存分析工具下载

MAT内存分析工具MAT是MemoryAnalyzerTool的简称,它是一款功能强大的Java堆内存分析器,可以用于查找内存泄漏以及查看内存消耗情况 。MAT是
基于Eclipse开发的一款免费的性能分析工具,读者可以在http://www.eclipse.org/mat/上下载并使用MAT 。
一,初识MAT在分析堆快照前,首先需要导出应用程序的堆快照 。在本书前文中提到的jmap、JConsole和VisualVM等工具都可以用于获得Java应用程序的堆快照文件 。此外,MAT本身也具有这个功能 。
如图6.66所示,在File菜单中选择AcquireHeapDump命令,在弹出对话框的当前Java应用程序列表中选择要分析的应用程序即可,如图6.67所示 。


MAT内存分析工具 mat内存分析工具下载

文章插图
MAT内存分析工具 mat内存分析工具下载

文章插图
除了直接在MAT中导出正在运行的应用程序堆快照外,也可以通过File菜单中的OpenHeapDump命令打开一个既存的堆快照文件 。
注意:使用MAT既可以打开一个已有的堆快照,也可以直接从活动Java程序中导出堆快照 。
图6.68所示为正常打开堆快照文件后的MAT界面 。
MAT内存分析工具 mat内存分析工具下载

文章插图
在图6.68的右侧界面中显示了堆快照文件的大小、类、实例和ClassLoader的总数;饼图中显示了当前堆快照中最大的对象 。将光标悬停在饼图中,可以在左侧的Inspector界面中查看该对象的详细信息 。在饼图中单击,可以对选中的对象进行更多的操作 。
单击工具栏上的柱状图按钮(如图6.69所示),可以查看当前堆的类信息,包括类的对象数量、浅堆(Shallow)大小和深堆(Retained)大小,如图6.70所示 。


MAT内存分析工具 mat内存分析工具下载

文章插图
通过柱状图界面,可以查找引用选中对象的对象集合以及选中对象所引用的对象集合 。如图6.71所示,选中java.util.Vector对象并右击,在弹出的右键菜单中选择Listobjects命令,弹出的withoutgoingreferences和withincomingreferences子命令分别表示查找java.util.Vector实例的引用对象,以及引用java.util.Vector实例的对象 。


MAT内存分析工具 mat内存分析工具下载

文章插图
注意:通过MAT,可以根据对象间的引用关系对内存中的对象进行分析 。
图6.72显示了选择withincomingreferences命令后的输出结果,展示了两个被主线程引用的java.util.Vector局部变量实例 。
为了方便查看,柱状图还可以根据ClassLoader和包对类进行排序 。图6.73显示了MAT的柱状图排序功能,以及一个按照包进行排序的柱状图输出命令 。


MAT内存分析工具 mat内存分析工具下载

文章插图
图6.72 引用关系查询结果
MAT内存分析工具 mat内存分析工具下载

文章插图
二,浅堆和深堆浅堆(ShallowHeap)和深堆(RetainedHeap)是两个非常重要的概念,它们分别表示一个对象结构所占用的内存大小和一个对象被执行GC操作后,可以真实释放的内存大小 。
浅堆是指一个对象所消耗的内存 。在32位系统中,一个对象引用会占据4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节 。
根据堆快照格式不同,对象的大小可能会向8字节进行对齐 。以String对象为例,图6.74显示了String对象的几个属性 。
3个int类型以及一个引用类型合计占用的内存为3×4+4=16字节,再加上对象头的8个字节,因此String对象占用的空间,即浅堆的大小是16+8=24字节 。浅堆的大小只与对象的结构有关,与对象的实际内容无关 。也就是说,无论字符串的长度是多少,内容是什么,浅堆的大小始终是24字节 。
MAT内存分析工具 mat内存分析工具下载

文章插图
深堆的概念略微复杂 。要理解深堆,首先需要了解保留集(RetainedSet) 。对象A的保留集指当对象A被垃圾回收后,可以被释放的所有的对象集合(包括对象A本身),即对象A的保留集可以被认为是只能通过对象A被直接或者间接访问到的所有对象的集合 。通俗地说,就是指仅被对象A所持有的对象的集合 。深堆是指对象的保留集中所有对象的浅堆之和 。
注意:浅堆指对象本身占用的内存,不包括其内部引用对象的大小 。一个对象的深堆指只能通过该对象访问到的(直接或间接)所有对象的浅堆之和,即对象被回收后,可以释放的真实空间 。