對象存活檢測機(jī)制
1.引用計(jì)數(shù)法
JVM早期使用的檢測活著的對象基本算法栓袖,原理是每個對象持有一個引用計(jì)數(shù)器匣摘,當(dāng)每個地方引用該對象則該對象的計(jì)數(shù)器進(jìn)行+1,當(dāng)這個引用失效后該對象的計(jì)數(shù)器進(jìn)行-1裹刮,當(dāng)該對象的計(jì)數(shù)器為0時候說明該對象就是垃圾音榜,這個算法存在弊端,無法處理循環(huán)引用的對象捧弃,導(dǎo)致回收不了這種垃圾的對象赠叼。
2.根搜索算法(gcroot算法)
gcroot是從根節(jié)點(diǎn)進(jìn)行引用,如果對象不在根節(jié)點(diǎn)范圍的引用該對象屬于gc回收的垃圾违霞。
根節(jié)點(diǎn)具體分為(1.jvm棧的棧幀中的本地變量表的引用 2.方法區(qū)靜態(tài)屬性引用 3.方法區(qū)中的常量引用 4.本地方法引用)嘴办。gcroot根節(jié)點(diǎn)使用引用類型分為四大類 強(qiáng)引用(StrongReference) 軟引用(softReference) 弱引用(weakReference)和虛引用(phantomReference),除了強(qiáng)引用外其他引用都會封裝在Reference里面。
????強(qiáng)引用:如User u = new User()這種方式引用的對象买鸽, 這種對象是不會被gc回收的户辞,即使jvm拋出oom也不會回收該對象,它會隨著程序結(jié)束而消亡癞谒。要想讓jvm回收只可以將強(qiáng)引用進(jìn)行弱化底燎,u=null;當(dāng)gcroot根節(jié)點(diǎn)引用不到弹砚,發(fā)生gc會將其回收掉双仍。
????軟引用:軟引用jvm在內(nèi)存充足的情況下不會回收此對象,只有在內(nèi)存緊張(oom之前)時候回收此對象桌吃,回收前將這些對象放入引用隊(duì)列中進(jìn)行回收朱沃。
????弱引用:jvm隨時可能回收此種類型對象,當(dāng)觸發(fā)gc時候?qū)⑦@些對象放入引用隊(duì)列中回收
????虛引用:和沒有引用一樣,無法獲取到強(qiáng)引用對象逗物,也是加入的引用隊(duì)列中
3.標(biāo)記清除算法
暫停應(yīng)用程序執(zhí)行搬卒,gc線程進(jìn)行掃描標(biāo)記沒有存活的對象進(jìn)行回收,這種方式會產(chǎn)生內(nèi)存碎片化翎卓。
4.標(biāo)記壓縮算法
這種方式與標(biāo)記清除算法類似契邀,不同點(diǎn)在于掃描到?jīng)]有存活的對象分配到同一內(nèi)存區(qū)域,將對象之前存放的內(nèi)存區(qū)域進(jìn)行整理合并之后回收沒有存活的那塊區(qū)域的對象失暴,碎片化極大的降低坯门,使內(nèi)存重復(fù)利用率大大的提升。
5.分區(qū)回收算法
將內(nèi)存均等份分區(qū)(常說的region區(qū))逗扒,程序產(chǎn)生的對象分配到不同的region區(qū)古戴,回收對象時候是對某個region區(qū)進(jìn)行回收,這個過程不會STW(暫停程序)矩肩,在不影響垃圾回收的程序線程可以和當(dāng)前region區(qū)的垃圾回收線程同步進(jìn)行现恼,這樣降低了對整個內(nèi)存垃圾回收的時間,提高程序響應(yīng)黍檩,可以理解為在整個回收過程中無stw現(xiàn)象產(chǎn)生
6.分代算法
每個對象都有生命周期述暂,存在不同生命周期的對象應(yīng)使用不同的算法進(jìn)行垃圾回收。提高效率建炫,分代常用的算法,gcroot疼蛾,復(fù)制算法肛跌,標(biāo)記壓縮算法等等
記憶集合
記憶集合指的是老年代對象引用指向新生代對象引用的集合,在介紹gcroot算法進(jìn)行搜索。現(xiàn)在有個D(老年代)引用指向C(新生代)這種對象如圖:
當(dāng)發(fā)生YONG GC時候 根據(jù)根搜索算法確定C是否被堆外引用察郁,那就需要遍歷老年代中所有對象是否引用該對象衍慎,這樣就會浪費(fèi)時間,jvm就引用了記憶集合(remember set)當(dāng)新生代的對象到達(dá)一定的年齡放入老年代時將該對象的引用新生代的對象引用關(guān)系放入到記憶集合中皮钠,如果沒有不用執(zhí)行此操作稳捆,這樣yong gc時候只需要在記憶集合中遍歷C是否被老年代引用。不用遍歷整個Old區(qū)麦轰,大大提高性能乔夯。記憶集合有個致命的缺點(diǎn)其實(shí)這種引用圖C和D是無法被回收的,因?yàn)橛洃浖洗嬖趯?dǎo)致C不能被回收款侵,D也就不能被回收末荐,這種方式就是典型的 "空間換時間" ,那么這種對象什么時候才能被回收?只能等到C到達(dá)年齡移到老年區(qū)新锈,發(fā)生gc才會被回收甲脏。記憶集依舊遵循垃圾回收原則:垃圾回收那些不可達(dá)的對象,但不保證所有不可達(dá)的對象都會被回收。
總結(jié)
垃圾回收算法大體包含:引用計(jì)數(shù)器算法块请,根搜索算法(gcRoot)娜氏,復(fù)制算法,標(biāo)記清除算法墩新,標(biāo)記壓縮算法贸弥,分區(qū)算法,分代算法抖棘。
為了提高gcRoot搜索算法jvm引入了"記憶集合"提高對可達(dá)對象的查找判斷茂腥。
end-------------------------------------------------------------
下一篇,介紹jvm的幾種垃圾回收器