對象存活檢測機(jī)制
1.引用計(jì)數(shù)法
JVM早期使用的檢測活著的對象基本算法,原理是每個(gè)對象持有一個(gè)引用計(jì)數(shù)器,當(dāng)每個(gè)地方引用該對象則該對象的計(jì)數(shù)器進(jìn)行+1,當(dāng)這個(gè)引用失效后該對象的計(jì)數(shù)器進(jìn)行-1,當(dāng)該對象的計(jì)數(shù)器為0時(shí)候說明該對象就是垃圾,這個(gè)算法存在弊端,無法處理循環(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)引用外其他引用都會(huì)封裝在Reference里面。
????強(qiáng)引用:如User u = new User()這種方式引用的對象, 這種對象是不會(huì)被gc回收的,即使jvm拋出oom也不會(huì)回收該對象,它會(huì)隨著程序結(jié)束而消亡。要想讓jvm回收只可以將強(qiáng)引用進(jìn)行弱化,u=null;當(dāng)gcroot根節(jié)點(diǎn)引用不到,發(fā)生gc會(huì)將其回收掉。
????軟引用:軟引用jvm在內(nèi)存充足的情況下不會(huì)回收此對象,只有在內(nèi)存緊張(oom之前)時(shí)候回收此對象,回收前將這些對象放入引用隊(duì)列中進(jìn)行回收。
????弱引用:jvm隨時(shí)可能回收此種類型對象,當(dāng)觸發(fā)gc時(shí)候?qū)⑦@些對象放入引用隊(duì)列中回收
????虛引用:和沒有引用一樣,無法獲取到強(qiáng)引用對象,也是加入的引用隊(duì)列中
3.標(biāo)記清除算法
暫停應(yīng)用程序執(zhí)行,gc線程進(jìn)行掃描標(biāo)記沒有存活的對象進(jìn)行回收,這種方式會(huì)產(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ū),回收對象時(shí)候是對某個(gè)region區(qū)進(jìn)行回收,這個(gè)過程不會(huì)STW(暫停程序),在不影響垃圾回收的程序線程可以和當(dāng)前region區(qū)的垃圾回收線程同步進(jìn)行,這樣降低了對整個(gè)內(nèi)存垃圾回收的時(shí)間,提高程序響應(yīng),可以理解為在整個(gè)回收過程中無stw現(xiàn)象產(chǎn)生
6.分代算法
每個(gè)對象都有生命周期,存在不同生命周期的對象應(yīng)使用不同的算法進(jìn)行垃圾回收。提高效率,分代常用的算法,gcroot,復(fù)制算法,標(biāo)記壓縮算法等等
記憶集合
記憶集合指的是老年代對象引用指向新生代對象引用的集合,在介紹gcroot算法進(jìn)行搜索?,F(xiàn)在有個(gè)D(老年代)引用指向C(新生代)這種對象如圖:
圖片.png
當(dāng)發(fā)生YONG GC時(shí)候 根據(jù)根搜索算法確定C是否被堆外引用,那就需要遍歷老年代中所有對象是否引用該對象,這樣就會(huì)浪費(fèi)時(shí)間,jvm就引用了記憶集合(remember set)當(dāng)新生代的對象到達(dá)一定的年齡放入老年代時(shí)將該對象的引用新生代的對象引用關(guān)系放入到記憶集合中,如果沒有不用執(zhí)行此操作,這樣yong gc時(shí)候只需要在記憶集合中遍歷C是否被老年代引用。不用遍歷整個(gè)Old區(qū),大大提高性能。記憶集合有個(gè)致命的缺點(diǎn)其實(shí)這種引用圖C和D是無法被回收的,因?yàn)橛洃浖洗嬖趯?dǎo)致C不能被回收,D也就不能被回收,這種方式就是典型的 "空間換時(shí)間" ,那么這種對象什么時(shí)候才能被回收?只能等到C到達(dá)年齡移到老年區(qū),發(fā)生gc才會(huì)被回收。記憶集依舊遵循垃圾回收原則:垃圾回收那些不可達(dá)的對象,但不保證所有不可達(dá)的對象都會(huì)被回收。
總結(jié)
垃圾回收算法大體包含:引用計(jì)數(shù)器算法,根搜索算法(gcRoot),復(fù)制算法,標(biāo)記清除算法,標(biāo)記壓縮算法,分區(qū)算法,分代算法。
為了提高gcRoot搜索算法jvm引入了"記憶集合"提高對可達(dá)對象的查找判斷。
end-------------------------------------------------------------
下一篇,介紹jvm的幾種垃圾回收器
