1. 程式人生 > >物件的建立過程

物件的建立過程

物件的建立過程

  1. 虛擬機器遇到new指令時,首先檢查這個指令的引數是否能在常量池中定位到一個類的符號引用,並檢查這個符號是否已被載入解析和初始化過。如果沒有,則必須要先執行相應的類載入的過程
  2. 檢查通過後,虛擬機器為新生物件分配記憶體。物件所需記憶體的大小在類載入完成後便可完全確定,為物件非配空間的任務等同於把一塊確定大小的記憶體從Java堆中劃分出來。

假如堆中的記憶體絕對規整,所有用過的記憶體放在一邊,空閒的另一邊,中間放著一個指標作為分界點的指示器,這種分配方式為指標碰撞。(Bump the Pointer)

如果堆中的記憶體並不規整,使用過和未使用過的相互交錯,那麼JVM需要維護一個列表記錄那些可用那些不可用,這稱為空閒列表。(Free List)


問題:併發情況下,出現正在給A物件分配記憶體,指標還沒來得及修改,物件B又同時使用了原來的指標分配記憶體。

解決辦法1:對分配空間的動作進行同步處理(原子性),實際上JVM採用CAS配上失敗重試的方式保持原子性。

解決辦法2:不同的執行緒分配在不同的空間,每個執行緒在Java堆中預先分配一小塊記憶體。既TLAB(Thread Local Allocation Buffer)。哪個執行緒要分配記憶體,就在那個執行緒的TLAB上分配。當TLAB用完並分配TLAB時才需要同步鎖定。

通過 -XX:+/-UseTLAB 設定使用TLAB


記憶體分配完成後,虛擬機器需要將分配到的記憶體空間都初始化為零值。如果使用TLAB,這一工作過程也可以提前至TLAB分配時進行。這一步保證物件不賦值也可以使用,程式能訪問到這些欄位的資料型別對應的零值(0,flase等)


上面工作完成後,從虛擬機器的視角來看,一個新的物件產生了,但從Java程式角度來看,物件才剛剛開始,方法還沒執行,所有欄位都還為0。