註意:本篇博客,主要參考自《深入理解Java虛擬機(第二版)》 1、對象在記憶體中存儲的佈局分為三塊 對象頭 存儲對象自身的運行時數據:Mark Word(在32bit和64bit虛擬機上長度分別為32bit和64bit),包含如下信息: 對象hashCode 對象GC分代年齡 鎖狀態標誌(輕量級鎖、
註意:本篇博客,主要參考自《深入理解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,沒有測試
- 基本數據類型與對應包裝類的選用
在實際使用中,我們會根據位元組數較小的一方來選用基本數據類型還是使用其包裝類。
- 在《第二章 JVM記憶體分配 》中說過,實際對象所占的記憶體大小在類載入完成後就可以知道了,具體是怎樣計算的,可以參看這一篇文章http://www.importnew.com/14948.html