(給ImportNew加星標,提高Java技能)
來自:唐尤華
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,這是另一個強大的堆轉儲分析工具,它能計算由於不良程式設計實踐浪費的記憶體大小,像如重覆物件、過度分配資料結構且利用不足、資料型別定義不佳等。
看完本文有收穫?請轉發分享給更多人
關註「ImportNew」,提升Java技能
喜歡就點「好看」唄~