Java 對象頭

一、引言

  • java對象頭很重要,synchronize、GC、HashCode、biasedLock、ObjectMonitor都是在對象頭上作文章。php

  • 其實整個Java能夠說是構建在oop-klass體系上的,相信從各類技術博客、書籍你們都瞭解很多。可是基本上都是32位虛擬機下,可能周志明大神的學習筆記太多。java

  • 本文不打算講講oop-klass體系(能力有限),只聊聊64位虛擬機下普通的對象頭,jdk1.8.0_221,jvm參數:-XX:-UseCompressedOops,但願對讀者有所幫助。數組

二、認識oop

  • oo-klass的基石之一,先來看看oop(實際上是個oopDesc *)
typedef class oopDesc* oop;

class oopDesc{
    friend class VMStructs;
 private:
  volatile markOop  _mark;
  union _metadata {
    Klass*      _klass;
    narrowKlass _compressed_klass;
  } _metadata;
}
複製代碼

2.一、 oop的繼承體系

  • 取自jdk8,從源碼能夠看出xxOop是xxxOopDesc*的別名。
typedef class oopDesc* oop;
typedef class instanceOopDesc* instanceOop;
typedef class arrayOopDesc* arrayOop;
typedef class objArrayOopDesc* objArrayOop;
typedef class typeArrayOopDesc* typeArrayOop;
複製代碼
  • 主要是instanceOopDesc和arrayOopDesc。均繼承自oopDesc,沒有擴充字段屬性,下文不在贅述。也就是說instanceOopDesc、arrayOopDesc的markword、klass屬性均來自oopDesc,關於arrayOopDesc稍微有點特殊,下文詳述。

2.2 、InstanceOopDesc

  • 普通的Java對象均是instanceOopDesc,不管是包裝類型仍是基本類型。
  • 🌰來了。

  • 可見普通類型的對象也被安排一個object header。

2.三、arrayOopDesc

  • objArrayOopDesc、typeArrayOopDesc繼承自arrayOopDesc,其中包裝類型的數組類型是objArrayOopDesc,基本類型數組是typeArrayOopDesc。

  • 上文提到了oop的屬性,其中arrayOopDesc有點特殊,它不只有markword、klass,還有個length屬性來記錄數組長度。可是翻看jdk源碼,arrayOopDesc除了繼承自arrayOopDesc,也沒有擴展任何屬性,那length屬性怎麼來的呢?其實這個length屬性屬於對象頭的一部分,它不是以一個獨立屬性的形式存在,而是在對象頭markword和klass以後固定的位置存儲的一個值。
  • 下面簡單示意能夠看出,64位虛擬機下,length出如今offset=16的位置。其中三、4等於數組長度毫不是偶然的,讀者能夠自行驗證。

  • 注意:對象頭與實例數據無關,其實arrayOopDesc的length屬於對象頭,不屬於data的一部分。

2.四、markword

  • markword是oop的一部分,其中hashcode、GC、輕量級鎖/重量級鎖/偏向鎖、分代年齡都是在markword上作文章。markword起始於對象頭offset=0的位置,在64位虛擬機上佔8個字節。

  • 上面這張圖你們都見過不少次了,從名稱中也能夠看出我上面一點所言不虛。那麼問題來了,不少人一眼看出你這篇文章上面8個字段64個bit好像除了一個看到個1,你沒有鎖標誌我能理解,hashcode你也吃了嗎?你隨便寫幾個對象hashcode都是0嗎?
  • 最開始我也詫異我骨骼驚奇(感受能夠人腦挖礦、手算md5了),開個玩笑。。。java這麼容易hash膨脹,我要不要轉行php?騷年,是你書讀的太少啊。🌰來了。

  • 仔細看圖,相信你就明白了。注意markword=00000008807e2501,其中unused25位,hashcode與integers1.hashcode()相等,2個標誌位也ok。jvm

  • 再看一個偏向鎖狀態的(標誌位101)oop

三、小結

  • 主要介紹了java對象頭oop,包括實例對象頭、數組對象頭。
  • 對對象頭中的markword結合demo進行簡單說明,拋磚引玉。至於偏向鎖、輕量級鎖、重量級鎖升級過程的markword的變化待後續可能有詳盡篇幅。不過都是在java對象頭中作文章,讀者能夠結合鎖升級流程圖自行驗證。
相關文章
相關標籤/搜索