Shallow Size and Retained Size
Shallow Size and Retained Size 的含義都是指的實例對象箭启,不是類本身亿眠。
下面將用 sampleClass 表示類Sample的一個實例(instance)
Shallow Size 含義
Shallow Size 就是對象本身所占用的大小,不包括其引用的對象。
舉個例子:
public class SampleClass {
// age 屬于 Shallow Size
private int age = 1;
// String 類型引用本身 name 屬于 Shallow Size唇辨,
// 被引用對象 "SOME_STRING" 不屬于 Sample 的實例Shallow Size
private String name = SOME_STRING;
// 數(shù)組所有內容都屬于 Shallow Size
private int[] ids = {1, 2, 3};
}
Retained Size 含義
針對可達對象
可達對象就是說免都,從 GC roots 開始搜索锉罐,能夠到達的對象,也就是說下一次GC不會被清理的對象绕娘,采用下面的計算方法來得到 Retained Size 對象
Retained Size的含義相對于Shallow Size 不太好理解脓规。依然是上面的例子,在不同的情況下险领,sampleClass 的Retained Size 并不相同抖拦。下面引用StackOverFlow上的一個回答來解釋這個問題。
Retained size of an object is its shallow size plus the shallow sizes of the objects that are accessible, directly or indirectly, only from this object. In other words, the retained size represents the amount of memory that will be freed by the garbage collector when this object is collected.
上圖應該比較容易理解舷暮,看起來每個對象的Retained Size 都符合公式( Retained Size = Shallow Size + 直接子對象的 Retained Size),并沒有什么問題噩茄,然后我們看另外一種引用關系中下面,Obj1 的Retained Size 就會發(fā)生變化。
第二種圖中绩聘,你會發(fā)現(xiàn)Obj2的Retained Size 不再符合我們剛剛總結出來的公式沥割,這是因為Obj2的直接子對象Obj5還被Obj6所引用,造成的結果就是凿菩,如果Obj2被回收机杜,Obj5并不會被回收,所以 Obj2 的Retained Size就不應該包括 Obj5 的Retained Size. 雖然 Obj2 的 Retained Size 發(fā)生了變化衅谷,但是 Obj1 的 Retained Size 并沒有發(fā)生變化椒拗。
針對不可達對象
指的是下一次 GC 會被清理的對象,也就是說沒有其他對象引用自己的對象获黔。
如果你嘗試使用 VisualVM 分析dump文件的時候蚀苛,你會發(fā)現(xiàn)有些對象的 Retained Size 居然是0,這個0就推翻了上面那種分析方法的的結論玷氏,覺得無論什么樣的對象肯定是會有 Shallow Size 的堵未,不可能為0。
通過分析最后可以這樣理解:針對不可達對象盏触,也就是可以完全被清除的對象渗蟹,Retained Size 都是0
附錄
理解誤區(qū)
好多人是簡單的將保留大小描述為,該對象本身和其直接引用或者間接引用的對象的大小的總和
赞辩。這種理解是片面的雌芽,就像上面例子中的 Obj2 一樣,如果按照這種理解就會得到錯誤的結論诗宣。