咱們知道在Java中基本數據類型的大小,例如int類型佔4個字節、long類型佔8個字節,那麼Integer對象和Long對象會佔用多少內存呢?本文介紹一下Java對象在堆中的內存結構以及對象大小的計算。數組
一個Java對象在內存中包括對象頭、實例數據和補齊填充3個部分:佈局
對象實際數據包括了對象的全部成員變量,其大小由各個成員變量的大小決定,好比:byte和boolean是1個字節,short和char是2個字節,int和float是4個字節,long和double是8個字節,reference是4個字節(64位系統中是8個字節)。優化
Primitive Type | Memory Required(bytes) |
---|---|
boolean | 1 |
byte | 1 |
short | 2 |
char | 2 |
int | 4 |
float | 4 |
long | 8 |
double | 8 |
對於reference類型來講,在32位系統上佔用4bytes, 在64位系統上佔用8bytes。ui
Java對象佔用空間是8字節對齊的,即全部Java對象佔用bytes數必須是8的倍數。例如,一個包含兩個屬性的對象:int和byte,這個對象須要佔用8+4+1=13個字節,這時就須要加上大小爲3字節的padding進行8字節對齊,最終佔用大小爲16個字節。spa
注意:以上對64位操做系統的描述是未開啓指針壓縮的狀況,關於指針壓縮會在下文中介紹。操作系統
這裏說明一下32位系統和64位系統中對象所佔用內存空間的大小:3d
MarkWord
是8字節,對象頭爲12字節;MarkWord
爲4字節(64位未開啓指針壓縮的爲8字節);從上文的分析中能夠看到,64位JVM消耗的內存會比32位的要多大約1.5倍,這是由於對象指針在64位JVM下有更寬的尋址。對於那些將要從32位平臺移植到64位的應用來講,平白無辜多了1/2的內存佔用,這是開發者不肯意看到的。指針
從JDK 1.6 update14開始,64位的JVM正式支持了 -XX:+UseCompressedOops 這個能夠壓縮指針,起到節約內存佔用的新參數。code
OOP的全稱爲:Ordinary Object Pointer,就是普通對象指針。啓用CompressOops後,會壓縮的對象:對象
固然,壓縮也不是全部的指針都會壓縮,對一些特殊類型的指針,JVM是不會優化的,例如指向PermGen的Class對象指針、本地變量、堆棧元素、入參、返回值和NULL指針不會被壓縮。
在Java程序啓動時增長JVM參數:-XX:+UseCompressedOops
來啓用。
注意:32位HotSpot VM是不支持UseCompressedOops參數的,只有64位HotSpot VM才支持。
本文中使用的是JDK 1.8,默認該參數就是開啓的。