MAT内存分析工具 mat内存分析工具下载( 二 )


下面这个例子很好地诠释了深堆的概念 。首先是表示点的类定义:


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

文章插图
接着是表示线的类定义:
MAT内存分析工具 mat内存分析工具下载

文章插图
主函数构造了a、b、c、d、e、f、g这7个点,以及aLine、bLine、cLine和dLine这4条线,并在程序最后将a、b、c、d、e这5个点设置为null 。具体代码如下:


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

文章插图


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

文章插图
这段代码的对象引用关系如图6.75所示,其中a、b、c、d、e对象在使用完成后被设置为null 。
MAT内存分析工具 mat内存分析工具下载

文章插图
根据Point类的结构,一个Point实例的浅堆大小为4×2+8=16字节,一个Line实例的浅堆大小为4×2+8=16字节 。使用MAT得到该示例的内存快照文件,如图6.76所示 。为了阅读方便,笔者将代码中的变量名标识到了内存快照中的对象上 。


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

文章插图
可以看到,所有的Point实例浅堆和深堆的大小都是16字节 。而dLine对象,浅堆为16字节,深堆也是16字节,这是因为dLine对象内的两个点f和g没有被设置为null,因此即使dLine被回收,f和g也不会被释放 。对象cLine内的引用对象d和e由于仅在cLine内还存在引用,因此只要cLine被释放,d和e必然也作为垃圾被回收,即d和e在cLine的保留集内,因此cLine的深堆为16×2+16=48字节 。
对于aLine和bLine对象,由于两者均持有对方的一个点,因此当aLine被回收时,公共点a在bLine中依然有引用存在,故不会被回收,点a不在aLine对象的保留集中,因此aLine的深堆大小为16+16=32字节 。对象bLine与aLine完全一致 。
在MAT中,无论是在柱状图还是对象列表中,选中对象并右击,在弹出的快捷菜单中都有ShowRetainedSet命令,它可用于显示指定类或者对象的保留集 。图6.77和图6.78分别为在bLine对象上进行该操作,以及bLine对象的保留集 。


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

文章插图


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

文章插图
三,支配树MAT提供了一个称为支配树(DominatorTree)的对象图 。支配树体现了对象实例间的支配关系 。在对象引用图中,所有指向对象B的路径都经过对象A,则认为对象A支配对象B 。如果对象A是离对象B最近的一个支配对象,则认为对象A为对象B的直接支配者 。支配树是基于对象间的引用图所建立的,它具有以下基本性质:
·对象A的子树(所有被对象A支配的对象集合)表示对象A的保留集(retainedset) 。
·如果对象A支配对象B,那么对象A的直接支配者也支配对象B 。
·支配树的边与对象引用图的边不直接对应 。
如图6.79所示,左图表示对象引用图,右图表示左图所对应的支配树 。对象A和B由根对象直接支配,由于在到对象C的路径中可以经过A,也可以经过B,因此对象C的直接支配者也是根对象 。对象F与对象D相互引用,因为到对象F的所有路径必然经过对象D,因此对象D是对象F的直接支配者 。而到对象D的所有路径中,必然经过对象C,即使是从对象F到对象D的引用,从根节点出发,也是经过对象C的,所以对象D的直接支配者为对象C 。


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

文章插图
同理,对象E支配对象G 。到达对象H的路径可以通过对象D,也可以通过对象E,因此对象D和E都不能支配对象H,而经过对象C既可以到达D也可以达到E,因此对象C为对象H的直接支配者 。
在MAT中,单击工具栏上的对象支配树按钮,如图6.80所示,可以打开对象支配树视图 。


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

文章插图
图6.81显示了对象支配树视图的一部分 。该截图显示部分main线程对象的直接支配对象,即main线程对象被回收后将被释放的所有对象的集合 。
注意:在对象支配树中,某一个对象的子树表示在该对象被回收后也将被回收的对象的集合 。
MAT内存分析工具 mat内存分析工具下载

文章插图
四,垃圾回收根在Java系统中,作为垃圾回收的根节点可能是以下对象之一 。