|
一個對象實例占用了多少字節(jié),消耗了多少內(nèi)存?這樣的問題在c或c++里使用sizeof()方法就可以得到明確答案,在java里好像沒有這樣的方法(java一樣可以實現(xiàn)),不過通過jmap工具倒是可以查看出一個對象的占用內(nèi)存的大小,這里介紹一種通過分析java代碼計算內(nèi)存使用情況的方法。 注意,一下討論的情況都是基于32位機(jī),不適用用64位機(jī),JVM是sun的HotSpot,不同的虛擬機(jī)實現(xiàn)可能會不同
規(guī)則一:每個對象被按照8bytes粒度對齊(數(shù)組除外)
在jvm中每個對象(數(shù)組除外)都有一個頭,這個頭有兩個字,第一個字存儲的時對象的一些標(biāo)志位信息,例如:鎖標(biāo)志位、經(jīng)歷了幾次gc等信息,第二個字是一個引用,指向了這個類的類信息。這里jvm給這兩個字留了8個字節(jié)的空間(這個為啥用8個字節(jié)空間不是很清楚,一個字即兩個字節(jié),我一直認(rèn)為4個字節(jié)就夠了) 按規(guī)則一:new Object();這個Object實例就占用了8個字節(jié)
規(guī)則二:為類屬性分配存儲空間時不是按照類中定義的屬性順序,而是按如下的順序: 1、double\long;----8bytes 2、int\float;----4bytes 3、char\short;----2bytes 4、boolean\byte;----1bytes 5、reference;----4bytes 例如: Java代碼 public class A { byte a; char b; int c; long d; Object e; }
屬性 需要字節(jié)數(shù) 累積字節(jié)數(shù) header 8bytes 8 long:d 8bytes 16 int:c 4bytes 20 char:b 2bytes 22 byte:a 1bytes 23 Object:e 4bytes 27 padding 5bytes 32
最后一行padding 5bytes的目的是,規(guī)則一中描述每個對象按照8個字節(jié)的粒度對齊,這樣下一個分配的對象的開始位置必須在8的倍數(shù)上,而離27最近的8的倍數(shù)是32,因此加了5bytes。A占用32bytes 可以用jmap看一下這個計算是否準(zhǔn)確
規(guī)則三:對于繼承時,要按照規(guī)則二先計算父類的類屬性占用情況,再按照規(guī)則二計算子類的類屬性占用情況,不能將父類和子類的屬性混合在一起按規(guī)則二分配。 例如: Java代碼 class B{ long a; int b; int c; }
class BB extends B{ long d; }
屬性 占用字節(jié)數(shù) 累計字節(jié)數(shù) header 8 8 a 8 16 b 4 20 c 4 24 d 8 32
這里累計字節(jié)正好是8的倍數(shù),滿足規(guī)則一,因此不用padding字節(jié)。BB對象內(nèi)存占用了32bytes
規(guī)則四:父類的最后一個屬性和子類第一個屬性必須按4個字節(jié)的倍數(shù)對齊 例如: Java代碼 class B{ long a; int b; char c; }
class BB extends B{ long d; }
屬性 占用的字節(jié) 累計字節(jié) head 8 8 a 8 16 c 2 18 padding 2 20 d 8 28 padding 4 32
第一次padding2是因為屬性c分配內(nèi)存后,不滿足父類最后一個屬性和子類第一個屬性按4字節(jié)粒度對齊(18除4除不開),因此需要添加兩個字節(jié)使其可以按4字節(jié)粒度對齊。 第二次paadding4是依據(jù)規(guī)則一
規(guī)則五:當(dāng)子類的第一個屬性是double或long,但是父類不能按8字節(jié)粒度對齊時,子類內(nèi)存分配時的順序?qū)⒉话匆?guī)則二進(jìn)行,而是按:先int\float、char\short、boolean\byte、reference、long\double
例如: Java代碼 class A{ byte a; }
class B extends A{ long b; short c; byte d; }
屬性 占用字節(jié)數(shù) 累計占用字節(jié)數(shù) head 8 8 a 1 9 padding 3 12 c 2 14 d 1 15 padding 1 16 b 8 24 第一次 padding 3是根據(jù)規(guī)則四 第二次 padding 1是因為b屬性是8個字節(jié),因此需要按8個字節(jié)粒度對齊。B占用24bytes
對于數(shù)組,與普通對象不同的是在頭部,頭部多了4個字節(jié)用于存儲長度信息。因此數(shù)組的head是12bytes而不是8bytes |
|
|