使用MAT时的Shallow Size和 Retained Size的区别
使用 MAT 时的 Shallow Size 和 Retained Size 的区别
编者注:本文为历史博文归档;涉及 JDK、框架与工具链版本请以当前官方文档为准。引用外链图片可能失效,阅读时请注意时效性。
所有具备 Heap Profiling(堆分析)功能的工具(如 MAT、Yourkit、JProfiler、TPTP 等)都会涉及两个核心概念:Shallow Size 和 Retained Size。
这两个概念在日常开发中并不常见,但它们对于理解内存占用至关重要。本文将对这两个名词进行详细解释。
Shallow Size
Shallow Size 指的是对象自身占用的内存大小,不包括它引用的其他对象。
- 非数组类型对象:大小等于对象头与它所有成员变量大小的总和。这其中还包括一些 Java 语言特性的数据存储单元(如对象头信息)。
- 数组类型对象:大小是数组元素对象的大小总和。
Retained Size
Retained Size 的计算公式如下:
Retained Size = 当前对象大小 + 当前对象可直接或间接引用到的对象的大小总和
- 间接引用的含义:若存在引用链 A -> B -> C,则 C 是 A 的间接引用对象。
- 实际意义:Retained Size 代表当前对象被 GC(垃圾回收)后,从 Heap(堆)上总共能释放掉的内存。
注意:在计算释放内存时,需要排除被 GC Roots 直接或间接引用的对象,因为这些对象暂时不会被当做 Garbage(垃圾)回收。
图解 Retained Size
通过下图可以更直观地理解 Retained Size 的计算逻辑。

在上图中,GC Roots 直接引用了 A 和 B 两个对象:
- A 对象的 Retained Size = A 对象的 Shallow Size
- B 对象的 Retained Size = B 对象的 Shallow Size + C 对象的 Shallow Size
这里不包括 D 对象,因为 D 对象被 GC Roots 直接引用,即使 B 被回收,D 依然存在。
如果 GC Roots 不引用 D 对象呢?

此时,引用关系发生变化:
- B 对象的 Retained Size = B 对象的 Shallow Size + C 对象的 Shallow Size + D 对象的 Shallow Size
参考资料
转载自:http://kenwublog.com/understand-shallow-and-retained-size-in-hprofling
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/shi-yong-mat-shi-de-shallow-size-he-retained-size-de-qu-bie.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。