我們在Java中的一個object物件在jvm記憶體中占用的空間大小是多少呢?
代碼如下:
Object o = new Object() ;
這句代碼執行時:
首先在該代碼執行時,是在一個方法內,方法的資料存在于堆疊幀,在堆疊中,拿出一塊空間,存放指向物件的指標的 o ,在堆中,new 出一個object物件,然后堆疊中的 o 指向堆中的物件,記憶體布局如圖所示:

那么,我們new出來的堆中的物件,具體的記憶體布局是什么樣的呢,我們通過使用一個openjdk的類,將該物件的相關資訊列印出來,
引入 Java Object Layout
新建一個maven 專案,配置 xml 檔案如下:
<dependencies> <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version> </dependency> </dependencies>
測驗代碼如下:
1 publicstaticvoidmain(String[]args){ 2 Objecto=newObject(); 3 System.out.println(ClassLayout.parseInstance(o).toPrintable()); 4 }
輸出結果為:
java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
輸出的 java.lang.Object 物件的記憶體布局的解釋
第一行 開始位置為0,大小為4個位元組 type Description 里面內容的描述 ,這里裝的是物件的頭資訊
第二行 從第4個位元組開始,還是4個位元組的大小,內容也還是物件頭
第三行 第8個位元組開始,還是4個位元組,也是物件頭
第四行 第12個位元組開始,4個位元組,補全對齊的
普通物件記憶體資訊
普通物件的記憶體資訊由4部分組成,
第一部分 markword 記錄關于鎖的資訊,synchronized的所有信心都記錄在這里,
第二部分為型別指標,指向當前物件所屬的class,用于標識物件到除錯于哪個類,
第三部分為物件里面的成員變數所占的空間,
第四部分為對齊,當物件整體位元組數不能被8整除的時候將物件補成能被8整除的大小,
因為cpu在讀記憶體里面值的時候,按照總線寬度讀取,如果可以被8整除,那么會提高讀取效率,
關于類指標壓縮
如果沒有開啟 UseCompressedClassPointers 類指標壓縮64位的虛擬機,一個指標的長度是64位,也就是說8個位元組,
但是如果開啟了UseCompressedClassPointers(作業系統默認開啟)這時候,型別指標,class pointer 就是4個位元組,
普通物件指標壓縮
UseCompressedOops:普通物件指標壓縮,oops: ordinary object pointer
成員變數指標的指向是否被進行壓縮,也是默認開啟,而且如果只開啟類指標壓縮,不開啟普通物件指標壓縮那么系統是會報錯的
結論:object物件,在記憶體中的堆中,無論是否開始指標壓縮,都是16個位元組,因為不壓縮的話,對齊的4個位元組就不存在了,在堆+堆疊中,如果開啟指標壓縮的話,那么是20個位元組,沒有開啟的話是24個位元組,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/154801.html
標籤:Java
