1. 程式人生 > >JVM學習筆記二

JVM學習筆記二

物件的建立

首先,檢查new指令的引數是否能在常量池中定位到一個類的符號引用,並且檢查該符號引用所代表的類是否已經被載入、解析、初始化過。如果沒有,需要 執行相應的類載入過程。

其次,虛擬機器為新生物件分配記憶體。物件所需的記憶體大小在類載入完畢後便可以確定。

然後,虛擬機器需要將分配的記憶體空間都初始化為零值(不包含物件頭),保證了物件例項欄位在Java程式碼中可以不賦值就直接使用。

接下來,虛擬機器對物件進行必要的設定,比如:該物件是哪個類的例項、如何找到類的元資料資訊、物件的雜湊碼、物件的GC分代年齡等資訊。存在在物件頭中。

虛擬機器視角,該物件已經建立完畢。

一般來說,執行new指令之後,會緊接著執行<init>方法,把物件按照寫作者的意願進行初始化,這樣一個物件才完全產生出來。

另附:

一、如何分配記憶體

  1. “指標碰撞”(Bump the Pointer):假設Java堆中是絕對規整的(用過的記憶體在一邊 空閒的記憶體在一邊 中間放一個指標作為分界點的指示器),分配記憶體就是把指標向空閒空間方向移動一塊與物件大小相等的距離。

  2. “空閒列表”(Free List):如果Java堆中不是規整的,已使用的和空閒的相互交錯,虛擬機器就必須維護一個列表,來記錄哪些記憶體塊是可用的,在分配的時候在列表中找一塊足夠大的空間劃分給物件例項,並且更新表上的記錄。

二、併發情況下如何在堆上為物件分配記憶體

  1. 對記憶體分配空間的動作進行同步處理(虛擬機器採用CAS

配失敗重試的方式來保證更新的原子性)

  2. 把記憶體分配的動作按照執行緒劃分在不同的空間之中進行。也就是每個執行緒在Java堆中預先分配一小塊記憶體,稱為本地執行緒分配緩衝(Thread Local Allocation Buffer,TLAB)。哪個執行緒需要分配記憶體,就在哪個執行緒的TLAB上分配,只有

  在TLAB用完並分配新的TLAB時,才需要同步鎖定。虛擬機器是否使用TLAB,可通過引數 -XX:+/-UseTLAB 引數來設定。