當(dāng)虛擬機(jī)遇到new指令的時候
檢查、確認(rèn)內(nèi)存大小和分配內(nèi)存、初始化內(nèi)存空間
1.檢查指令的參數(shù)能否在常量池中定位到一個類的符合引用,并且檢查這個符號引用代表的類有沒有被加載、解析和初始化過
2.如果沒有,則執(zhí)行類加載過程
3類加載檢查通過后,便可以確認(rèn)對象所需的內(nèi)存大小,如何進(jìn)行分配內(nèi)存
4.指針碰撞:可以理解為一邊是使用的內(nèi)存一邊是空的,夾在中間的指針,分配內(nèi)存的時候就是指針往空的內(nèi)存挪一丟丟距離,即和對象所需內(nèi)存大小一樣的內(nèi)存空間。 高效簡單!
5.空閑列表:就是內(nèi)存不夠整齊,坑坑洼洼的,得專門記錄哪塊內(nèi)存可用,分配時找到大的內(nèi)存空間給對象。比較復(fù)雜!
6.如果是使用復(fù)制算法和標(biāo)記壓縮法? 使用指針碰撞
? ?如果是使用標(biāo)記清除算法,則使用空閑列表
7.分到內(nèi)存后要將分配到的內(nèi)存空間都初始化為0,不包含對象頭(不知道為什么,日后研究)
8.設(shè)置對象,將一些信息存放到對象頭(哪個類的實例,如何找到類的元數(shù)據(jù)信息,hash碼,GC分代年齡)。到這一步對象就產(chǎn)生了!
對象的內(nèi)存布局
1.對象頭(兩部分)
Mark World:存放運行時數(shù)據(jù)(hashcoad,GC分代年齡,鎖的狀態(tài)標(biāo)志,線程持有的鎖)
類型指針:對象指向它的類型元數(shù)據(jù)指針
2.實例數(shù)據(jù)
3.對齊填充:占位符作用
對象的訪問定位:通過棧的reference
1.句柄訪問:Java堆中專門劃分內(nèi)存當(dāng)作句柄池,reference存儲的是對象的句柄地址
好處:儲存的是穩(wěn)定的句柄地址,GC時候?qū)ο笪恢冒l(fā)生變化只需要修改句柄中的實例數(shù)據(jù)指針
2.直接指針訪問:referenc直接存儲的是對象地址,速度較快
