JVM——java虛擬機建立對象與尋址對象

JAVA虛擬機建立對象的流程算法

 

JAVA對象的結構安全

空間分配

空間分配的兩種方式

指針碰撞

    當已分配空間被集中存放,已分配和未分配空間使用一個指針來標記時,分配新的空間只須要移動該空間便可,此方法爲指針碰撞。適用於GC算法會作COMPACT的狀況。線程

空閒列表

    當已分配的空間是分散存放時,虛擬機必須維護一個記錄了哪些內存塊是可用的列表,此爲空閒列表,須要分配新空間時只須要從該列表中獲取。指針

解決空間分配線程安全問題的兩種方式

CAS方式失敗重試

    顧名思義,趕上分配時的線程衝突時,會再次進行空間分配直至成功。實現簡單直觀可是效率較低對象

空間劃分

    爲每一個線程分配單獨的一塊空間,該空間只用來給該線程作建立對象分配空間時使用,這單獨的空間被稱爲本地線程分配緩衝(Thread Local Allocation Buffer,TLAB)。當該線程的TLAB分配光了後,才須要同步鎖定,效率較高。是否使用TLAB能夠經過虛擬機參數指定。blog

設置對象頭(對象管理的必要信息)

  空間初始化成0後(初始化不包含對象頭),須要針對對象設置一些必要信息,如:對象歸屬於哪一個類、對象的hash碼、對象的GC分代年齡等,這些信息都放在對象頭中。根據虛擬機狀態——如是否使用偏向鎖,設置對象頭。內存

對象頭包含信息

    對象頭包含兩部分信息:同步

      • 運行時數據(hash碼、GC分代年兩、持有鎖、鎖標識狀態、偏向線程ID),這部分數據被稱爲Mark Word。
      • 類型指針,用來講明該對象是哪一個類的實例。

設置對象實例數據

  對象的實例數據主要是根據JAVA代碼的編寫生成的,包含包括父類在內的各類類型的字段,其字段安排的順序受虛擬機實現及代碼的編寫影響。虛擬機

虛擬機安排字段的方式

    一、相同寬度的字段放在一塊兒hash

    二、父類的字段放在子類的前面

    三、窄小的變量也會被安排在父類的字段空隙中(C++的內存安排規則,HotSpot VM是由C++語言編寫)

填充字段

  HotSpot VM要求對象的其實位置必須是8字節的整數倍,也就是說對象必須是8字節的整數倍,因此須要填充佔位(這也是一句C++的規則來的)。

 

對象的定位

  JAVA程序訪問對象須要經過棧上的reference數據操做堆上的具體對象。reference對象要麼經過指向句柄再指向對象實例,要麼直接指向對象實例。

以句柄的方式訪問

    使用句柄方式訪問對象實例,須要在堆中劃分出一起句柄池,句柄與指針相似,記錄了具體的實例所存放的地址。這種方式的好處是reference是穩定的,當對象實例地址改變時,只需改變句柄中的對象實例指針。

 

以指針直接訪問

    以指針方式訪問對象實例,是經過reference直接指向對象實例,優勢是速度快,由於比句柄訪問方式少了一次尋址的過程。

 

PS:對象實例數據指的是具體的對象,對象類型對象指的是該實例數據對象所屬的Class類對象。

相關文章
相關標籤/搜索