在Java中沒有sizeof運算符,所以沒辦法知道一個對象到底占用了多大的空間,但是在分配對象的時候會有一些基本的規則,我們根據這些規則大致能判斷出來對象大小。
對象的頭部至少有兩個WORD,如果是數組的話,那么三個WORD,內容如下:
首先,任何對象都是8字節對齊,屬性按照[long,double]、[int,float]、[char,short]、[byte,boolean]、reference的順序存放,舉個例子:
public class Test {
byte a;
int b;
boolean c;
long d;
Object e;
}
如果這個對象的屬性按照順序存放的話,要占用的空間為:head(8) + a(1) + padding(3) + b(4) + c(1) + padding(7) + d(8) + e(4) + padding(4) = 40。但是按照這個規則得到:head(8) + d(8) + b(4) + a(1) + c(1) + padding(2) + e(4) + padding(4) = 32。可以看到節省了不少空間。
在涉及繼承關系的時候有一個基本的規則:首先存放父類中的成員,接著才是子類中的成員,舉個例子:
class A {
long a;
int b;
int c;
}
class B extends A {
long d;
}
這樣存放的順序及占用空間如下:head(8) + a(8) + b(4) + c(4) + d(8) = 32。那如果父類中的屬性不夠八個字節怎么辦?這樣就有了新的一條規則:父類中后一個成員與子類的個成員的間隔如果不夠4個字節,此時需要擴展到4個字節的基本單位,舉個例子:
class A {
byte a;
}
class B extends A {
byte b;
}
那么此時占用的空間如下:head(8) + a(1) + padding(3) + b(1) + padding(3) = 16。顯然這種方式比較浪費空間,那么就有了:如果子類的個成員是double或者long,并且父類并沒有用完8個字節,JVM會破壞規將較小的數據填充到該空間,舉個例子:
class A {
byte a;
}
class B extends A {
long b;
short c;
byte d;
}
此時占用的空間如下:head(8) + a(1) + padding(3) + c(2) + d(1) + padding(1) + b(8) = 24。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。