一色查、Java采用可達(dá)性算法
虛擬機(jī)采用可達(dá)性分析來判斷對象是否存活的。
它們已GC root對象為起點(diǎn)撞芍,向下搜索所有和GC root對象直接或間接關(guān)聯(lián)對象秧了。所走過的路徑為引用鏈。當(dāng)一個對象沒有到GC root的路徑時認(rèn)為該對象不可用序无。
在圖中obj4和obj5將被認(rèn)為是可回收對象验毡,因?yàn)闆]有關(guān)聯(lián)到GC ROOT的路徑
二、可以作為GC ROOT的對象
1.虛擬機(jī)棧中局部變量引用對象
2.類的靜態(tài)屬性引用對象
3.常亮引用對象
4.native方法引用對象
三帝嗡、強(qiáng)引用關(guān)系
1.強(qiáng)引用:只要有引用關(guān)系晶通,那么就不被回收
2.軟引用:當(dāng)系統(tǒng)內(nèi)存不足時被回收
3.弱引用:只要GC就回收
4.虛引用:能夠在垃圾回收時收到一個系統(tǒng)發(fā)出的通知,和弱引用強(qiáng)度一致
四哟玷、虛擬機(jī)垃圾回收的機(jī)制
1.首先會進(jìn)行一次篩選標(biāo)記狮辽,如果對象不可達(dá),將進(jìn)行篩選
2.篩選條件是有沒有必要調(diào)用finalize()方法碗降,當(dāng)對象沒有重寫該方法隘竭,或者finalize方法已經(jīng)被調(diào)用過,那么將不被執(zhí)行讼渊。如果認(rèn)為可以調(diào)用,那么將加入到F-QUEUE隊列中
3.所有在隊列中的對象都被執(zhí)行第二輪標(biāo)記尊剔,開啟一個線程調(diào)用隊列中的finalize方法爪幻,如果這時候有對象的finalize方法中讓該對象和任何對象關(guān)聯(lián),都將被移除隊列
finalize方法的優(yōu)先級很低
public static A a=null;
publc class A{
protected void finalize() throws Throwable{
a=this;
}
}
main{
a=new A();
a=null;
// gc會調(diào)用finalize方法须误,讓對象自身進(jìn)行一次拯救挨稿。這里A的方法又重新關(guān)聯(lián)了一個引用。
System.gc();
Thread.sleep(500);
}
四京痢、類的回收
符合以下三點(diǎn)的類可以被回收:
1.當(dāng)堆中不存在任何該類的實(shí)例
2.加載該類的ClassLoader被回收
3.Class沒有被任何地方反射到
//控制類的回收
-Xnoclassage:
五奶甘、垃圾收回算法
1.標(biāo)記清楚法
標(biāo)記出要清理的,然后進(jìn)行清理祭椰。會產(chǎn)生大量的不連續(xù)的內(nèi)存
2.復(fù)制清除法
分配一個Edrn區(qū)和兩個大小相等的survivor空間臭家。每次清理Edrn和一塊survivor區(qū),把剩下的復(fù)制到另一塊方淤。Edrn和survivor區(qū)的空間是8:1:1的關(guān)系钉赁。
3.標(biāo)記整理法
同樣采用標(biāo)記清理,但是在標(biāo)記后將所有不清理的對象移動到內(nèi)存的一邊携茂,清理另一邊的內(nèi)存你踩。
OopMap協(xié)助GC
虛擬機(jī)中有一個OopMap的數(shù)據(jù)結(jié)構(gòu)來負(fù)責(zé),當(dāng)類加載的完成后,虛擬機(jī)就把對象內(nèi)的引用關(guān)系記錄下來
GC的時間點(diǎn)
虛擬機(jī)有safePoint機(jī)制带膜,當(dāng)程序執(zhí)行到“安全點(diǎn)時”(方法調(diào)用吩谦,異常跳轉(zhuǎn)等就會產(chǎn)生安全點(diǎn))。虛擬機(jī)采用主動中斷的機(jī)制膝藕。當(dāng)GC需要中斷線程時會設(shè)置一個標(biāo)志位式廷,每個線程都去讀哪個標(biāo)志位,當(dāng)為true時束莫,就主動中斷懒棉。