關於對象頭以及Synchronized鎖狀態的理解

最近在看OpenJdk的源碼,對對象頭部分有了一個更直觀的理解。同時,對象頭中的MarkWord部分,又包含了對不同鎖狀態的標識,故以此爲起點,梳理下不同鎖狀態的表示及不同鎖狀態的轉換。

1、對象頭

    JVM內部,使用 OOP-Klass 二分模型來表示類和對象,OOP用來表示Java對象實例,Klass用來表示Java類。在Java應用程序運行過程中,每創建一個Java對象,在JVM內部就會相應地創建一個OOP對象來對應(具體爲instanceOopDesc對象)。而每加載一個Java類,也會對應創建一個Klass對象來對應(具體爲instanceKlass對象)。

    Java對象在內存中的佈局,可分爲連續的兩部分:instanceOopDesc + 實例數據。數組對象爲:arrayOopDesc + 實例數據。

對象的內存佈局

    這裏的 instanceOopDesc 與 arrayOopDesc,即爲對象頭。對象頭中的Mark Word,即 OopDesc 基類中的 _mark 成員,存儲對象運行時信息,如Hash Code、Age、鎖狀態標識、線程持有的鎖、偏向線程ID、偏向時間戳等。對象頭中的元數據指針,即 OopDesc 基類中的 _metadata 成員,指向描述對象所對應 Java 類的 Klass 對象。

2、鎖狀態

     目前 Synchronized 鎖狀態有四種,級別從低到高分別是:無所、偏向鎖、輕量級鎖和重量級鎖。對應到 Mark Word 裏,就如下圖所示:

對象狀態 25bit 4bit 1bit 2bit
23bit 2bit 是否偏向鎖 鎖標識
Unlocked Hashcode Age 0 01
Light-weight locked 鎖記錄指針 00
Heavy-weight locked Monitor指針 10
Mraked for GC Forward指針 11
Biased/biasable 線程ID Epoch Age 1 01

    3、鎖狀態轉換

    無鎖:

    偏向鎖:

    輕量級鎖:

    重量級鎖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章