附 Java對象內存布局


注意:本篇博客,主要參考自《深入理解Java虛擬機(第二版)》

 

1、對象在內存中存儲的布局分為三塊

  • 對象頭
    • 存儲對象自身的運行時數據:Mark Word(在32bit和64bit虛擬機上長度分別為32bit和64bit),包含如下信息:
      • 對象hashCode
      • 對象GC分代年齡
      • 鎖狀態標志(輕量級鎖、重量級鎖)
      • 線程持有的鎖(輕量級鎖、重量級鎖)
      • 偏向鎖相關:偏向鎖、自旋鎖、輕量級鎖以及其他的一些鎖優化策略是JDK1.6加入的,這些優化使得Synchronized的性能與ReentrantLock的性能持平,在Synchronized可以滿足要求的情況下,優先使用Synchronized,除非是使用一些ReentrantLock獨有的功能,例如指定時間等待等。
    • 類型指針:對象指向類元數據的指針(32bit-->32bit,64bit-->64bit(未開啟壓縮指針),32bit(開啟壓縮指針))
      • JVM通過這個指針來確定這個對象是哪個類的實例(根據對象確定其Class的指針)

  • 實例數據:對象真正存儲的有效信息
  • 對齊填充
    • JVM要求對象的大小必須是8的整數倍,若不是,需要補位對齊

2、注意

  • Mark Word具有非固定的數據結構,以便在極小的空間內存儲盡量多的信息
  • 如果對象是一個數組,對象頭必須有一塊兒用於記錄數組長度的數據。JVM可以通過Java對象的元數據確定對象長度,但是對於數組不行。
  • 對於對象頭長度而言
    • 32bit虛擬機一定是32bit+32bit,即8字節
    • 64bit虛擬機若沒有開啟了壓縮指針,是64bit+64bit,即16字節,若開啟了壓縮指針,是64bit+32bit,即12字節(不是8bit的倍數)
    • -XX:+UseCompressedOops:開啟壓縮指針
    • 在《深入理解Java虛擬機(第二版)》中,說對象頭是8字節或16字節,不知道是不是有誤,自己的系統不是64bit,沒有測試
  • 基本數據類型與對應包裝類的選用

在實際使用中,我們會根據字節數較小的一方來選用基本數據類型還是使用其包裝類。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM