1. 程式人生 > 實用技巧 >2.3 HotSpot虛擬機器物件

2.3 HotSpot虛擬機器物件

深入理解JVM虛擬機器 第二章 java記憶體區域與記憶體溢位異常 2.3 HotSpot虛擬機器物件

2.3.1 物件的建立

分配記憶體的方式

1 指標碰撞

在這裡插入圖片描述
假設Java堆中記憶體是絕對規整的,所有用過的記憶體放在一邊,空閒的記憶體放在另一邊,中間放著一個指標作為分界點的指示器,那所分配記憶體就僅僅是把那個指標指向空閒空間那邊挪動一段與物件大小相等的距離,這個分配方式叫做“指標碰撞”

2 空閒列表

如果Java堆中的記憶體並不是規整的,已使用的記憶體和空閒的記憶體相互交錯,那就沒辦法簡單地進行指標碰撞了,虛擬機器就必須維護一個列表,記錄上哪些記憶體塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給物件例項,並更新列表上的記錄,這種分配方式成為“空閒列表”

選擇哪種分配方式由Java堆是否規整決定,而Java堆是否規整又由所採用的垃圾收集器是否帶有壓縮整理功能決定。

3 分配記憶體的併發問題

在分配記憶體的時候會出現併發的問題,比如在給A物件分配記憶體的時候,指標還沒有來得及修改,物件B又同時使用了原來的指標進行了記憶體的分片。
  有兩個解決方案:
  1、對分配的記憶體的動作進行同步處理:CAS配上失敗重試的方式保證更新操作的原子性
  2、把記憶體分配的動作按照執行緒劃分在不同的空間之中進行,即每個執行緒在java堆中分配一塊小記憶體,稱為本地緩衝區,那個執行緒需要分配記憶體,就需要在本地緩衝區上進行,只有當緩衝區用完並分配新的緩衝區的時候,才需要同步鎖定,

建立物件

在記憶體分配完成後,虛擬機器需要將分配到的記憶體空間都初始化為零值(不包括物件頭)
接下來,虛擬機器要對物件進行必要的設定,如這個物件是哪個類的例項,如何才能找到類的元資料資訊、物件的雜湊碼、物件的GC分代年齡等資訊。這些資訊放在物件的物件頭中。
現在,物件才剛剛開始,因為還沒有執行init方法,所有的欄位都為0。

執行new指令之後會接著執行Init方法,進行初始化,這樣一個物件才算產生出來。