JAVA虛擬機建立對象的流程算法
JAVA對象的結構安全
當已分配空間被集中存放,已分配和未分配空間使用一個指針來標記時,分配新的空間只須要移動該空間便可,此方法爲指針碰撞。適用於GC算法會作COMPACT的狀況。線程
當已分配的空間是分散存放時,虛擬機必須維護一個記錄了哪些內存塊是可用的列表,此爲空閒列表,須要分配新空間時只須要從該列表中獲取。指針
顧名思義,趕上分配時的線程衝突時,會再次進行空間分配直至成功。實現簡單直觀可是效率較低對象
爲每一個線程分配單獨的一塊空間,該空間只用來給該線程作建立對象分配空間時使用,這單獨的空間被稱爲本地線程分配緩衝(Thread Local Allocation Buffer,TLAB)。當該線程的TLAB分配光了後,才須要同步鎖定,效率較高。是否使用TLAB能夠經過虛擬機參數指定。blog
空間初始化成0後(初始化不包含對象頭),須要針對對象設置一些必要信息,如:對象歸屬於哪一個類、對象的hash碼、對象的GC分代年齡等,這些信息都放在對象頭中。根據虛擬機狀態——如是否使用偏向鎖,設置對象頭。內存
對象頭包含兩部分信息:同步
對象的實例數據主要是根據JAVA代碼的編寫生成的,包含包括父類在內的各類類型的字段,其字段安排的順序受虛擬機實現及代碼的編寫影響。虛擬機
一、相同寬度的字段放在一塊兒hash
二、父類的字段放在子類的前面
三、窄小的變量也會被安排在父類的字段空隙中(C++的內存安排規則,HotSpot VM是由C++語言編寫)
HotSpot VM要求對象的其實位置必須是8字節的整數倍,也就是說對象必須是8字節的整數倍,因此須要填充佔位(這也是一句C++的規則來的)。
JAVA程序訪問對象須要經過棧上的reference數據操做堆上的具體對象。reference對象要麼經過指向句柄再指向對象實例,要麼直接指向對象實例。
使用句柄方式訪問對象實例,須要在堆中劃分出一起句柄池,句柄與指針相似,記錄了具體的實例所存放的地址。這種方式的好處是reference是穩定的,當對象實例地址改變時,只需改變句柄中的對象實例指針。
以指針方式訪問對象實例,是經過reference直接指向對象實例,優勢是速度快,由於比句柄訪問方式少了一次尋址的過程。
PS:對象實例數據指的是具體的對象,對象類型對象指的是該實例數據對象所屬的Class類對象。