天蓬老师2017-04-18 10:51:59
想說清楚shallow size就必須提到Retained Size。
shallow size: 表示自身物件所佔用的大小。
retained size: 自身物件+引用物件的retained大小。
先借用一張圖,這張圖更能清楚的表示他們之間的計算關係。
B的shallow size = B;
B的retained size = B shallow size + C retained size + D retained size;
在舉例之前,首先要了解JAVA物件在堆中的存儲,我們以32位元JVM虛擬機為例:
JAVA物件在堆中共有3個部分組成:
物件頭
物件頭又包含兩部分資料;
一:運行時資料。 32位元JVM為32位元即4byte.64位元為8byte.
二:型別指標。
實例資料
即存放實例變數的數據,變數型別包括兩種 基本型別變數和參考變數。
基本型別變數所佔據的位元組大小就不說了,引用變數我們存放的是指標。
填充資料
物件儲存空間為8byte的整數倍,如果物件頭+實例資料不足8byte的整數倍,則進行填充。
說到引用型別大小,32位元虛擬機器下引用佔據4byte. 64位元虛擬機器下方如果不開啟指標壓縮,則引用佔據8byte。
下面我們根據例子進行說明:
public class TestObjSize {
private int a = 1;
private boolean b = true;
private TestObjSize testObjSize;
public static void main(String[] args) {
Object object = new Object();
TestObjSize test = new TestObjSize();//这个new出来的对象记为obj1
test.testObjSize = new TestObjSize();//这个new出来的对象记为obj2
System.out.println(object.hashCode());
System.out.println(test.hashCode());
try {
Thread.sleep(3000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
因為shallow size與實例變數是否有引用無關,所我們先分析下**TestObjSize的shallow size,
shallow size = 4byte(對象頭) + 4byte(類型指標) + 4byte(int a) + 1byte(boolean b ) + 4byte(TestObjSize引用) = 17;**
17不是8的整數倍所以會有7個byte的填充數據,最終TestObjSize類型的實例對象的shallow size = 24;
根據範例我們看到obj2物件的testObjSize = null,
obj2的retained size = obj2的shallow size = 24;
obj1物件的testObjSize為obj2,所以obj1的retained sizeobj1物件的testObjSize是obj2,所以obj1的retained sizeobj1物件的testObjSize為obj2,所以obj1的retained sizeobjize 1的48;
最後附上heapdump!
如有錯誤,請看客指證。