动态

详情 返回 返回

JAVA併發編程——Java對象內存佈局和對象頭 - 动态 详情

1.對象在堆內存中佈局

2.對象的對象頭

3.對象的實例數據

4.對象的對齊填充

5.看看Object的對象頭

6.看看自定義對象的對象頭

7.總結

1.對象在堆內存中佈局
當我們寫入這樣一行代碼

Object object = new Object();

的時候,我們都知道它會在我們的JVM堆->新生區->伊甸園區新建一個對象,但是我們可能只是知道這個對象在哪兒,但是對這個對象的內存結構卻知之甚少,今天我們就來細説一下,JAVA對象的內存佈局。

我們先來看這樣一張圖:
image.png
java對象在內存中的佈局分為以下三個部分:
1)對象頭
2)實例數據
3)對齊填充

接下來我們來詳細介紹以下這三個部分。

2.對象的對象頭
首先是對象頭,這是java對象內存佈局中,最重要的一個部分,它分為了兩個部分:
1)對象標記Mark Word
2)類型指針(類元信息)

首先是對象標記:
image.png
默認存儲的是HashCode,分代年齡,鎖標誌位,GC標記等信息。
這些信息是與對象自身定義無關的數據,所以MarkWork被設計成一個非固定的數據結構,以便在小的空間內能夠儘量存儲更多的數據。
它會根據對象的狀態複用自己的存儲空間,也就是説在運行期間,MarkWork裏的存儲對象會隨着鎖標誌位的改變而發生變化

類型指針(類元信息):

image.png

對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例

對象頭的大小:
在64位系統中,Mark Word佔了8個字節,類型指針佔了8個字節,一共是16個字節

3.對象的實例數據

這個部分應該是我們每天接觸的部分,我們平時寫的字段都在這裏,還包括父類的屬性信息(如果是數組的實例部分還包括數組的長度),這部分內存按照4個字節對齊。

4.對象的對齊填充
虛擬機要求對象的起始地址必須是8字節的整數倍,填充數據不是必須存在的,如果對象頭+對象的實例數據不是8的整數倍,那麼對象的對齊填充就會按照8字節補充對齊

5.看看Object的對象頭
在使用java查看Object的對象頭之前,我們要先引入一個工具類,這樣才可以更方便地查看對象頭。

        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>

接着我們小試一下,看看我們平時使用的Object類的對象頭有幾個字節:

 public static void main(String[] args) {

        Object o = new Object();

        System.out.println(ClassLayout.parseInstance(o).toPrintable());

    }

image.png

發現這裏的問題沒有,前面我們説,對象頭佔16個字節,但是它這裏只佔12個字節?最後一排顯示了丟失?所以對象頭究竟是佔16個字節還是12個字節呢
答案是————都對。 因為JVM默認幫我們開啓了對象頭的壓縮,打開這個壓縮,對象頭就佔12位,關閉這個壓縮,對象頭就佔16位,我們再來試一下:
我們先在JVM運行的時候,使用這個參數:-XX:-UseCompressedClassPointers 這個參數就是關閉壓縮參數。

image.png

然再運行,獲得的結果為:
image.png

6.看看自定義對象的對象頭
Object的對象頭看完了,我們看看自定義的對象頭又有什麼區別。

我們先自定義一個對象

class MyObj{

    private Integer id;

    private String name;

    private Integer age;

    private String address;

    private Integer status;


    private Date createTime;

    private Date updateTime;


}

我們發現,對象實例數據區域明顯多了很多自定義的字段,並且進行了對齊填充。

image.png

7.總結
今天我們學習了JAVA對象在內存中的佈局,這一部分內容是為了為講解鎖升級做鋪墊。

user avatar mannayang 头像 u_16297326 头像 u_17513518 头像 journey_64224c9377fd5 头像 sofastack 头像 debuginn 头像 xuxueli 头像 tech 头像 lenglingx 头像 u_15702012 头像 jiangyi 头像 chuanghongdengdeqingwa_eoxet2 头像
点赞 54 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.