MAT 专题
Shallow Size (对象自身占用的内存大小)
Retained Size (被GC后Heap上释放的内存大小)
with outgoing references 我引用了谁 (查看对象为什么消耗内存,查看对象引用的其他对象)
with incoming references 谁引用了我(查看对象被谁引用)
MAT分析工具中 with incoming references 的意思
ListObjects >with incoming references【谁引用了我】
表示的是 当前查看的对象,被外部应用
ListObjects>with outGoing references【我引用了谁】
表示的是 当前对象,引用了外部对象
测试:
A类,里面有一个B对象
在out里面看到了B, 而in里面没有看到B
shallow heap和retained heap
直译过来是浅层堆和保留堆的意思。先说一说其基本的概念。
shallow heap
表示对象本身占用内存的大小,也就是对象头加成员变量(不是成员变量的值)的总和。
如一个引用占用32或64bit,一个integer占4bytes,Long占8bytes等。
如简单的一个类里面只有一个成员变量int i,那么这个类的shallow size是12字节,因为对象头是8字节,成员变量int是4字节。
常规对象(非数组)的Shallow size有其成员变量的数量和类型决定,数组的shallow size有数组元素的类型(对象类型、基本类型)和数组长度决定。
对象的值是分配给存储对象本身的内存量,不考虑所引用的对象。常规(非数组)对象的浅大小取决于其字段的数量和类型。数组的浅尺寸取决于数组的长度及其元素(对象、基本类型)的类型。一组对象的浅尺寸表示该集合中所有对象的浅尺寸之和。
retained heap
如果一个对象被释放掉,那会因为该对象的释放而减少引用进而被释放的所有的对象(包括被递归释放的)所占用的heap大小,即对象被垃圾回收器回收后能被GC从内存中移除的所有对象之和。相对于shallow heap,Retained heap可以更精确的反映一个对象实际占用的大小(若该对象释放,retained heap都可以被释放)。
https://zhuanlan.zhihu.com/p/111762137
定位大对象(方法一)
MAT中的Histogram,可显示出每个类产生的实例数量,以及所占用的内存大小;
Shallow Heap 和 Retained Heap分别表示对象自身不包含引用的大小和对象自身并包含引用的大小。默认的大小单位是 Bytes,可以在 Window - Preferences 菜单中设置单位,图中设置的是KB。
https://www.cnblogs.com/rb2010/p/14741674.html
http://smallnetvisitor.iteye.com/blog/1826434
mac下配置mat的jvm参数:
/Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini
$cat MemoryAnalyzer.ini -startup ../Eclipse/plugins/org.eclipse.equinox.launcher_1.5.700.v20200207-2156.jar --launcher.library ../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.1100.v20190907-0426 -vm /Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/Home/bin/java -vmargs -Xmx1024m -Dorg.eclipse.swt.internal.carbon.smallFonts -XstartOnFirstThread
cd /Applications/mat.app/Contents/Eclipse vim MemoryAnalyzer.ini -------------> 这里添加上面的代码 -vm /Library/java/JavaVirtualMachines/jdk-11.jdk/Contents/Home/bin -------------> 添加完毕之后, 进行保存 :wq!
运行user任务管理器查看到的pid号:
基于jmap导出的堆信息:
jmap -dump:live,format=b,file=dump.bin pid 使用jmap来抓dump,在抓dump的时候,我们会把堆全部扒下来: jmap -dump:format=b,file=path pid 然后会生成一个几百M的包,让运维人员从生产环境拖下来再传给你,然后你用jvisualvm打开,等你打开这个dump的时候,看到你想看的内存的时候,基本上半天时间已经过去了。 其实我们丢了一个很重要的参数:live,这个参数表示我们需要抓取目前在生命周期内的内存对象,也就是说GC收不走的对象,然后我们绝大部分情况下,需要的看的就是这些内存。如果我们把这个参数加上: jmap -dump:live,format=b,file=path pid 那么抓下来的dump会减少一个数量级,在几十M左右,这样我们传输,打开这个dump的时间将大大减少,为解决故障赢取了宝贵的时间。
用装了mat插件的eclipse打开firstHeap.bin文件
选择Leak Suspects Reports模式,finish
点击details
这些对象有可能会溢出,然后我们打开OQL窗口
执行如下OQL语句
也就是说这个是null,但是仍然有强引用存在,gc的时候是不能回收的,这样就会出现内存的溢出问题
不懂就按F1,关于OQL有详细介绍,或进官网 mat Querying Heap Objects:http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Ftasks%2Fqueryingheapobjects.html
http://www.cnblogs.com/o-andy-o/archive/2013/06/11/3132316.html
对象大小:对象大小即Shallow size,是指对象本身的大小。 关联大小:即Retained size,是指对象本身的大小,加上它引用并使其存活的对象的大小。换句话说,关联大小就是回收该对象后能释放的堆空间的大小。该大小需要重点关注。
所有包含Heap Profling功能的工具(MAT,IBM HA, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size.
这是两个在平时不太常见的名词,本文会对这两个名词做一个详细的解释。
Shallow Size
对象自身占用的内存大小,不包括它引用的对象。
针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。
针对数组类型的对象,它的大小是数组元素对象的大小总和。
Retained Size
Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用)
换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。
不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。
看图理解Retained Size
上图中,GC Roots直接引用了A、B和D三个对象。
A对象的Retained Size=A对象的Shallow Size
B对象的Retained Size=B对象的Shallow Size + C对象的Shallow Size
这里不包括D对象,因为D对象被GC Roots直接引用。
如果GC Roots不引用D对象呢?
此时,
B对象的Retained Size=B对象的Shallow Size + C对象的Shallow Size + D对象的Shallow Size
http://bjyzxxds.iteye.com/blog/1532937
JVM 内存分析神器 MAT: Incoming Vs Outgoing References 你真的了解吗?
Incoming References: 引用了当前对象的对象
Outgoing References: 当前对象引用的对象
让我们通过示例来了解有关 Incoming references 和 Outgoing references 的更多知识。例如,一个应用程序的源代码如下所示
public class A { private C c1 = C.getInstance(); } public class B { private C c2 = C.getInstance(); } public class C { private static C myC = new C(); public static C getInstance() { return myC; } private D d1 = new D(); private E e1 = new E(); } public class D { } public class E { } public class SimpleExample { public static void main (String argsp[]) throws Exception { A a = new A(); B b = new B(); } }
现在,如果要为上述示例应用程序以图形方式绘制对象,则其外观将如下所示:
图 1:示例应用程序的对象引用图
对象 A 和对象 B 持有对象 C 的引用
对象 C 持有对象 D 和对象 E 的引用
在这个示例项目中,让我们具体分析下对象 C 的 Incoming references 和 Outgoing references 。
对象 C 的 Incoming References
拥有对象 C 的引用的所有对象都称为 Incoming references。
在此示例中,对象 C 的“Incoming references”是对象 A、对象 B 和 C 的类对象 。
为了证实这个判断,我们从上述示例应用程序中捕获了堆 Dump 文件,并将其载入到 Eclipse MAT 中进行分析。
下图是 Eclipse MAT 针对对象 C 报告的 Incoming references
在"Dominator Tree"中的 Object C 上单击鼠标右键,然后选择"List Objects",再选择 ”with incoming references“时,Eclipse MAT 会生成上图的报告。报告中展示对象 C 的 Incoming references 为对象 A、对象 B 和 C 的类对象。
Eclipse MAT 还显示了用于引用对象 C 的变量,可以看到使用变量“c1”引用对象 C 的对象 A,类似地,还报告了用于引用对象 C 的其他变量。
对象 C 的 Outgoing References
对象 C 引用的所有对象都称为 Outgoing References。
在此示例中,对象 C 的“outgoing references”是对象 D、对象 E 和 C 的类对象。以下是 Eclipse MAT 针对对象 C Outgoing references 的报告
在"Dominator Tree"中的 Object C 上单击鼠标右键,然后选择"List Objects",再选择 ”with incoming references“时,Eclipse MAT 会生成上图的报告。报告中展示对象 C 的 Incoming references 为对象 D、对象 E 和 C 的类对象。Eclipse MAT 还按显示对象 C 引用的其他对象。可以看到对象 C 使用变量 d1 引用了对象 D。类似地,报告还显示了对象 C 中使用的其他变量。
通过本文主要阐述了 Incoming references and Outgoing references 之间的区别。
原文:https://dzone.com/articles/eclipse-mat-incoming-outgoing-references
https://cloud.tencent.com/developer/article/1530223
MAT上展示的默认单位是Byte
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步