Eclipse MAT: Shallow Heap Vs Retained Heap 你理解的對嗎抄伍?
作者:Ram Lakshmanan艘刚,原文:Eclipse MAT: Shallow Heap Vs. Retained Heap
有沒有想過 Shallow 和 Retained heap 之間的區(qū)別?
Eclipse MAT(內(nèi)存分析器工具)是分析 JVM 堆 Dump 文件的強大工具截珍。當嘗試分析內(nèi)存相關的問題時攀甚,它非常方便。在 Eclipse MAT 中岗喉,報告了兩種類型的對象大星锒取:
- Shallow Heap
- Retained Heap
在本文中,我們主要討論它們之間的區(qū)別钱床,并探討它們的計算方式荚斯。
通過示例理解知識會更容易,咱們來看看這樣一個例子查牌。例如事期,假設你的應用程序具有這樣的對象模型,如圖 1 所示:
圖1:內(nèi)存中的對象
- 對象 A 持有對象 B 和 C 的引用僧免。
- 對象 B 持有對象 D 和 E 的引用。
- 對象 C 持有對象 F 和 G 的引用捏浊。
另外懂衩,我們假設每個對象占用 10 個字節(jié)的內(nèi)存。在這種場景下金踪,我們來開始分析吧浊洞。
Shallow Heap 大小
請記住:對象的 Shallow heap 是其自身在內(nèi)存中的大小胡岔。由于在我們的示例中法希,每個對象占用大約 10 個字節(jié),因此每個對象的 Shallow heap 大小為 10 個字節(jié)靶瘸。很簡單苫亦。
B 的 Retained Heap 大小
從圖 1 中,您可以注意到對象 B 持有對象 D 和 E 的引用怨咪。因此屋剑,如果對象 B 是從內(nèi)存中被垃圾回收,則將不再有對對象 D 和 E 的引用诗眨。這意味著此時 D 和 E 也可以被垃圾收集唉匾。Retained heap 指的就是在垃圾回收特定對象時將釋放的內(nèi)存量。因此匠楚,B 的保留堆大小為:
= B 的 shallow heap 大小 + D 的 shallow heap 大小 + E 的 shallow heap 大小
= 10 bytes + 10 bytes + 10 bytes
= 30 bytes
因此巍膘,B 對象的 Retained heap 大小為 30 字節(jié)
C 的 Retained Heap 大小
對象 C 擁有對象 F 和 G 的引用厂财。如果對象 C 是從內(nèi)存中垃圾回收的,將不再持有對對象 F 和 G 的引用峡懈。這意味著此時 F 和 G 也可以被垃圾回收璃饱。 因此,C 的 Retained Heap 大小為:
= C 的 shallow heap 大小 + F 的 shallow heap 大小 + G 的 shallow heap 大小
= 10 bytes + 10 bytes + 10 bytes
= 30 bytes
因此逮诲,C 對象的 Retained heap 大小為 30 字節(jié)
A 的 Retained Heap 大小
對象 A 持有對象 B 和 C 的引用帜平,而對象 B 和 C 又持有對對象 D、E 以及 F梅鹦、G 的引用裆甩。因此,如果對象 A 是從內(nèi)存中垃圾回收的齐唆,則將不再有對 B嗤栓、C、D箍邮、E茉帅、F 和 G 對象的引用《П祝基于此理解堪澎,我們來計算下 A 的 Retained Heap 大小。
A 的 Retained Heap 大小為:
= A 的 shallow heap 大小 + B 的 shallow heap 大小 + C 的 shallow heap 大小 + D 的 shallow heap 大小 + E 的 shallow heap 大小 + F 的 shallow heap 大小 + G 的 shallow heap 大小
= 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes + 10 bytes
= 70 bytes
最后我們可以得出味滞,A 的 Retained heap 大小是 70 字節(jié)樱蛤。
D、E剑鞍、F昨凡、G 的 Retained Heap 大小
D 的 Retained heap 大小與其 Shallow heap 大小相同,就是 10 個字節(jié)蚁署,因為 D 不持有對任何其他對象的引用便脊。因此,如果 D 獲得了垃圾回收光戈,則不會從內(nèi)存中刪除其他的任何對象哪痰。同理,E久妆、F 和 G 的 Retained heap 大小也只有 10 個字節(jié)妒御。
圖 2:對象的 Shallow and Retained Heap 大小
咱們再來點更有趣的吧
現(xiàn)在,讓我們的來點更加有趣的吧镇饺,以便讓你對 Shallow heap 和 Retained heap 有更加透徹的了解乎莉。在下面的示例中,讓對象 H 開始持有對 B 的引用。注意對象 B 已經(jīng)被對象 A 引用了⊥锟校現(xiàn)在哼鬓,兩個家伙 A 和 H 都持有對象 B 的引用。在這種情況下边灭,讓我們研究 Retained heap 計算將會發(fā)生什么變化异希。
圖 3:新增對 B 的引用
在這種情況下,對象 A 的 Retained heap 大小將從之前的 70 減小到 40 個字節(jié)绒瘦。是不是很吃驚称簿? 如果對象 A 被垃圾回收了,則將僅會影響 C惰帽、F 和 G 對象的引用憨降。因此,僅對象 C该酗、F 和 G 將被垃圾回收授药。另一方面,由于 H 持有對 B 的活動引用呜魄,因此對象 B悔叽、D 和 E 將繼續(xù)存在于內(nèi)存中。因此爵嗅,即使 A 被垃圾回收娇澎,B、D 和 E 也不會從內(nèi)存中刪除睹晒。因此趟庄,A 的 Retained heap 大小為:
= A 的 shallow heap 大小 + C 的 shallow heap 大小 + F 的 shallow heap 大小 + G 的 shallow heap 大小
= 10 bytes + 10 bytes + 10 bytes + 10 bytes
= 40 bytes.
A 的總 Retained heap 大小將變?yōu)?40 個字節(jié)。所有其他對象 Retained heap 大小將保持不變册招,因為它們的引用沒有變化岔激。
希望本文能夠讓你了解 Eclipse MAT 中的 Shallow heap 大小 和 Retained heap 大小計算方式勒极。