Eclipse MAT:浅堆 vs 保留堆
来自:唐尤华
https://dzone.com/articles/eclipse-mat-shallow-heap-retained-heap
有没有想要搞清楚浅堆(Shallow Heap)和保留堆(Retained Heap)之间的区别?
Eclipse MAT(内存分析器工具)是功能强大的堆转储分析工具,用来调试与内存相关的问题非常方便。 在 Eclipse MAT 中,会报告两种类型的对象大小:
浅堆
保留堆
在本文中,让我们一起研究它们之间的区别,并探索它们是如何计算出来的。

图1 内存中的对象
通过示例可以更轻松地掌握新概念。假设应用程序有一个对象模型,如图1所示:
对象 A 持有对象 B 和 C 的引用
对象 B 持有对象 D 和 E 的引用
对象 C 持有对象 F 和 G 的引用
假设每个对象占用10个字节的内存。现在,让我们基于这个场景开始研究。
1. 浅堆的大小
记住:对象的浅堆指它在内存中的大小。在示例中,每个对象大约占10个字节,所以每个对象的浅堆大小是10个字节,非常简单。
2. B 的保留堆大小
从图1可以看到,物体 B 持有对物体 D 和 E 的引用。 因此,如果对象 B 从内存中被垃圾回收,那么就不再持有对象 D 和 E 的活动引用。这意味着 D 和 E 也可以被垃圾回收。 保留堆指当特定对象被垃圾回收后即将释放的内存大小。 因此,B 的保留堆大小:
= B 的浅堆大小 + D 的浅堆大小 + E 的浅堆大小
= 10 bytes + 10 bytes + 10 bytes
= 30字节
因此 B 的保留堆大小为30字节。
3. C 的保留堆大小
对象 C 包含对象 F 和 G 的引用,因此,如果对象 C 从内存中被垃圾回收,那么就不再持有对象 F 和 G 的引用。这意味着 F 和 G 也可以被垃圾收集。C 的保留堆大小:
= C 的浅堆大小 + F 的浅堆大小 + G 的浅堆大小
= 10 bytes + 10 bytes + 10 bytes
= 30字节
因此 C 的保留堆大小也是30字节。

图2 对象浅堆的大小和保留堆大小
4. A 的保留堆大小
对象 A 持有对象 B 和 C 的引用,而对象 B 和 C 又持有对象 D、 E、 F 和 G 的引用,因此,如果对象 A 从内存中被垃圾回收,那么对象 B、 C、 D、 E、 F 和 G 的引用就不存在了。
因此 A 的保留堆大小:
= A 的浅堆大小 + B 的浅堆大小 + C 的浅堆大小 + D 的浅堆大小 + E 的浅堆大小 + F 的浅堆大小 + G 的浅堆大小
= 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes
= 70字节
这时我们可以得出结论,A 的保留堆大小为70字节。
5. D、 E、 F 和 G 的保留堆大小
D 的保留堆大小为10字节,但这只包括它们的浅堆大小。这是因为 D 不包含任何其他对象的活动引用。因此,如果 D 被垃圾回收,不会从内存中删除任何其他对象。同样道理,E、 F 和 G 的保留堆大小也只有10字节。
6. 让我们把研究变得更有趣
现在,让我们把研究变得更有趣一点,这样能够对浅堆和保留堆大小理解得透彻。在示例中让对象 H 加入对 B 的引用。注意,对象 B 已被对象 A 引用,现在 A 和 H 持有对象 B 的引用。 这种情况下,让我们研究一下保留堆大小会发生什么改变。

图3 对象 B 的新引用
在这种情况下,对象 A 的保留堆大小将减少到40字节。吃惊不?疑惑吗?
如果对象 A 被垃圾回收,那么将对象 C、 F 和 G 的引用将不复存在。因此,只有对象 C、 F 和 G 会被垃圾回收。另一方面,对象 B、 D 和 E 将继续存在于内存中,因为 H 持有对 B 的活动引用。因此,即使 A 被垃圾回收,B、 D 和 E 也不会从内存中删除。
因此,A 的保留堆大小为:
= A 的浅堆大小 + C 的浅堆大小 + F 的浅堆大小 + G 的浅堆大小
= 10 bytes + 10 bytes + 10 bytes + 10 bytes
= 40字节
A 的总保留堆大小将变为40字节。所有其他对象的保留堆大小保持不变,因为它们的引用没有变化。
希望本文有助于澄清 Eclipse MAT 中浅堆大小和保留堆大小的计算原理。你还可以考虑使用 HeapHero,这是另一个强大的堆转储分析工具,它能计算由于不良编程实践浪费的内存大小,像如重复对象、过度分配数据结构且利用不足、数据类型定义不佳等。
https://mp.weixin.qq.com/s/D7xf2m2-q0EmSZsMY0sG5A
Eclipse MAT:浅堆 vs 保留堆的更多相关文章
- Eclipse MAT 安装及使用
Eclipse MAT官方网页:https://www.eclipse.org/mat/downloads.php 一.MAT是什么? MAT(Memory Analyzer Tool),一个基于Ec ...
- Eclipse MAT内存分析工具(Memory Analyzer Tool)
MAT内存分析工具 MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器.可以用于查找内存泄露以及查看内存消耗情况.MAT是基于Eclipse开发的,是一款免费的性能分 ...
- Heap堆分析(堆转储、堆分析)
一.堆直方图 减少内存使用时一个重要目标,在堆分析上最简单的方法是利用堆直方图.通过堆直方图我们可以快速看到应用内的对象数目,同时不需要进行完整的堆转储(因为堆转储需要一段时间来分析,而且会消耗大量磁 ...
- 【转】Eclipse MAT内存分析工具(Memory Analyzer Tool)
Eclipse MAT内存分析工具(Memory Analyzer Tool) MAT内存分析工具# MAT是Memory Analyzer的简称,它是一款功能强大的Java堆内存分析器.可以用于查找 ...
- 十二、jdk工具之jcmd介绍(堆转储、堆分析、获取系统信息、查看堆外内存)
目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...
- 使用AndroidStudio dump heap,再用 Eclipse MAT插件分析内存泄露
1.eclipse mat插件的安装 Help->Install new software,如下图,一直下一步即可 2.AndroidStudio dump heap 3.AndroidStud ...
- Eclipse MAT: Understand Incoming and Outgoing References
引用:http://xmlandmore.blogspot.hk/2014/01/eclipse-mat-understand-incoming-and.html?utm_source=tuicool ...
- java performance tools / NetBeans Profiler / Sun BTrace / Eclipse MAT / IBM ISA
s Oracel Performace Analyzer NetBeans Profiler Eclipse MAT Sun BTrace IBM ISA end
- 堆和索引堆的实现(python)
''' 索引堆 ''' ''' 实现使用2个辅助数组来做.有点像dat.用哈希表来做修改不行,只是能找到这个索引,而需要change操作 还是需要自己手动写.所以只能用双数组实现. #引入索引堆的核心 ...
随机推荐
- JMS学习以及jms的实现activeMq
1.JMS规范介绍: http://www.cnblogs.com/hapjin/p/5431706.html http://elim.iteye.com/blog/1893038 http://bl ...
- 分形之拆分三角形(Split Triangle)
前面讲了谢尔宾斯基三角形,它是不停地将一个三角形拆分三个与之相似的三角形.这一节给大家展示的图形是将一个等腰钝角三角形不停地拆分两个与之相似的三角形. 核心代码: static void SplitT ...
- 分形之二叉树(Binary Tree)
上一篇文章讲的是分形之树(Tree),这一篇中将其简化一下,来展示二叉分形树的生长过程. 核心代码: static void FractalBinaryTree(const Vector3& ...
- 个人作业四--Alpha阶段个人总结
一.个人总结 在alpha 结束之后, 每位同学写一篇个人博客, 总结自己的alpha 过程: 请用自我评价表:http://www.cnblogs.com/xinz/p/3852177.html 有 ...
- uwp 用win2d获取图片主调颜色
win10在设置颜色里有个从“背景图片中选取一种主题颜色”的选项,还有在很多内容展示软件中都使用了这样的功能. 现在我们需要在 nuget 引用 win2d.uwp 和 Toolkit.uwp 两个库 ...
- 【译】准备好你求职时候用的 GitHub 账号
我目前正在招聘,很多人分享了他们的GitHubs个人资料和项目,但是维护得很差,所以我决定为活跃的求职者写一个小指南. 无论是否合理,技术招聘人员倾向于从您的GitHub个人资料中推断出很多关于您的信 ...
- 通过Metasploit生成各种后门
生成windows后门 1.首先生成后门 [root@localhost ~]# msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ ...
- underscore.js源码研究(4)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- C#6.0语言规范(十二) 数组
数组是一种数据结构,包含许多通过计算索引访问的变量.包含在数组中的变量(也称为数组的元素)都是相同的类型,这种类型称为数组的元素类型. 数组具有确定与每个数组元素相关联的索引数的等级.数组的等级也称为 ...
- 小记 ArchLinux 下 Typora 无法输入中文
今天准备写一篇 Linux 下的打印机文章,打开 Typora 时我发现不管我怎么设置都无法输入中文. pacman -R typora pacman -S typora 重新安装是无效的,我突然想起 ...