HotSpot虛擬機(jī)使用可達(dá)性分析算法確定對(duì)象是否可以被GC。
可達(dá)性分析算法從一系列GCRoot對(duì)象開(kāi)始苫幢,向下搜索引用鏈访诱,如果一個(gè)對(duì)象沒(méi)有與任何GCRoot對(duì)象關(guān)聯(lián),這個(gè)對(duì)象就會(huì)被判定為可回收對(duì)象韩肝。
GCRoot包括以下對(duì)象:
- 虛擬機(jī)棧上的本地變量表引用的對(duì)象
- 方法區(qū)中類的靜態(tài)屬性引用的對(duì)象
- 方法區(qū)中常量引用的對(duì)象
- 本地方法棧中JNI引用的對(duì)象
這一過(guò)程稱為根節(jié)點(diǎn)枚舉触菜,也就是垃圾回收中的標(biāo)記過(guò)程,當(dāng)前所有的垃圾收集器哀峻,在標(biāo)記階段都必須停止所有java執(zhí)行線程(stop the world)涡相,以保證對(duì)象引用狀態(tài)不會(huì)發(fā)生變化。
HotSpot虛擬機(jī)作為準(zhǔn)確式虛擬機(jī)剩蟀,維護(hù)了一個(gè)專門的映射表(OopMap)記錄哪些位置存放著對(duì)象引用催蝗,來(lái)快速完成根節(jié)點(diǎn)枚舉過(guò)程。
為每一個(gè)操作記錄OopMap不現(xiàn)實(shí)育特,HotSpot虛擬機(jī)引入了safePoint丙号。
safePoint是程序中的某些位置,線程執(zhí)行到這些位置時(shí)且预,線程中的某些狀態(tài)是確定的槽袄,在safePoint可以記錄OopMap信息,線程在safePoint停頓锋谐,虛擬機(jī)進(jìn)行GC。
線程停頓方式有兩種截酷,搶先式中斷和主動(dòng)式中斷:
- 搶先式中斷:虛擬機(jī)需要GC時(shí)涮拗,中斷所有線程,讓沒(méi)有到達(dá)safePoint的線程繼續(xù)執(zhí)行至saftPoint并中斷
- 主動(dòng)式中斷:虛擬機(jī)不直接中斷線程迂苛,而是在內(nèi)存中設(shè)置標(biāo)志位三热,線程檢查到標(biāo)志位被設(shè)置,運(yùn)行至saftPoint時(shí)主動(dòng)中斷
safePoint一般出現(xiàn)在以下位置:
- 循環(huán)體的結(jié)尾
- 方法返回前
- 調(diào)用方法的call之后
- 拋出異常的位置
這些位置保證線程不會(huì)長(zhǎng)時(shí)間運(yùn)行而無(wú)法到達(dá)safePoint三幻,避免其他線程都停頓等待本線程就漾。
safePoint無(wú)法解決線程未達(dá)到safePoint并處于休眠或等待狀態(tài)的情況,此時(shí)引入safeRegion的概念念搬。
safeRegion是代碼中的一塊區(qū)域或線程的狀態(tài)抑堡,在safeRegion中摆出,線程執(zhí)行與否不會(huì)影響對(duì)象引用的狀態(tài)。線程進(jìn)入safeRegion會(huì)給自己加標(biāo)記首妖,告訴虛擬機(jī)可以進(jìn)行GC偎漫;線程準(zhǔn)備離開(kāi)safeRegion前會(huì)詢問(wèn)虛擬機(jī)GC是否完成。