垃圾回收算法與垃圾回收器

在現(xiàn)行的垃圾回收算法中主要有以下幾種:

1.標(biāo)記-清除算法

標(biāo)記-清除算法是最基本的算法,后續(xù)的算法都是在這個(gè)基礎(chǔ)上對(duì)其不足進(jìn)行改進(jìn)而得到的。

這個(gè)算法主要分為兩步:1 標(biāo)記所有活動(dòng)的對(duì)象;2? 清除已經(jīng)死亡的對(duì)象(標(biāo)記了的是活動(dòng)的對(duì)象,未標(biāo)記的就是可清除的對(duì)象)

第一步 :標(biāo)記所有活動(dòng)的對(duì)象? (另一種說(shuō)法是標(biāo)記所有需要回收的對(duì)象,無(wú)論是哪一種,其原理是一致的)

標(biāo)記使用的是 深度優(yōu)先遍歷 (根 -左-右),原因是內(nèi)存使用量要比 廣度優(yōu)先遍歷 (層次遍歷)要小。

具體實(shí)現(xiàn):首先要標(biāo)記根直接引用的對(duì)象,然后進(jìn)行遞歸,偽代碼就是:

mark(obj){

? ? ? ? if(obj.mark == FALSE)//如果沒(méi)有標(biāo)記

? ? ? ? ? ? ? obj.mark =TRUE //則設(shè)置為標(biāo)記

? ? ? ? for(child : children(obj))//遞歸處理子對(duì)象

? ? ? ? ? ? ? mark(*child)

}

判斷對(duì)象是否存活用的是前面介紹過(guò)的 對(duì)象的可達(dá)性分析

第二步:清除所有沒(méi)有標(biāo)記的對(duì)象

在這一步,我們遍歷整個(gè)java堆,按順序一個(gè)一個(gè)的遍歷對(duì)象的標(biāo)記標(biāo)志位

1.設(shè)置了標(biāo)志位的,表示是存活的對(duì)象,將標(biāo)志位設(shè)為false,為下一次GC 的標(biāo)記 做準(zhǔn)備

2.沒(méi)有設(shè)置標(biāo)志位的,表示當(dāng)前對(duì)象已經(jīng)可以回收

標(biāo)記-清除算法示意圖

該回收算法的優(yōu)缺點(diǎn)

1.優(yōu)點(diǎn):算法簡(jiǎn)單,實(shí)現(xiàn)容易

2 缺點(diǎn):一個(gè)是效率不高二個(gè)是內(nèi)存碎片化。在標(biāo)記清除之后會(huì)產(chǎn)生大量的不連續(xù)的內(nèi)存碎片,空間碎片太多會(huì)導(dǎo)致在需要分配較大的對(duì)象時(shí),無(wú)法找到足夠連續(xù)的內(nèi)存而不得不提前觸發(fā)下一次GC。

3.標(biāo)記-清除 算法使用的時(shí)空閑鏈表

后面的算法均時(shí)根據(jù)該算法的缺點(diǎn)進(jìn)行改進(jìn)而衍生出來(lái)的

2.復(fù)制算法

原理:將可用內(nèi)存分為大小相等的兩塊,每次使用其中一塊,當(dāng)使用的那一塊內(nèi)存用完后,將存活的對(duì)象復(fù)制到另一塊上,然后一次性清理掉用完的那塊空間,如此往復(fù)。

這樣設(shè)計(jì)的目的時(shí)為了 解決效率問(wèn)題,實(shí)現(xiàn)了傳統(tǒng)意義上的空間換時(shí)間。

復(fù)制算法執(zhí)行時(shí)分為三個(gè)重要步驟

1.標(biāo)記存活對(duì)象

2.拷貝存活對(duì)象(已經(jīng)標(biāo)記的對(duì)象)到新的內(nèi)存區(qū)域,并更新對(duì)象指針。

3.一次性清理已使用的內(nèi)存空間


復(fù)制算法示意圖

復(fù)制算法的優(yōu)點(diǎn)

優(yōu)點(diǎn) :實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效,不會(huì)發(fā)生內(nèi)存碎片化(移動(dòng)指針,按序分配內(nèi)存)

缺點(diǎn):內(nèi)存使用率低下(將內(nèi)存一分為二,每一次只有一半的內(nèi)存可用),存活對(duì)象較多時(shí),效率同樣不高

由于最原始的算法內(nèi)存使用率太低,后來(lái)的商業(yè)虛擬機(jī)在這基礎(chǔ)上有一定的改進(jìn)。

在新生代中的對(duì)象98%的對(duì)象是“朝生夕死”,所以并不需要以1:1 的比例來(lái)分配 from 與 To 的空間,而是將內(nèi)存分為一塊較大的Eden空間跟兩塊較小的 Survivor空間(HotSpot中默認(rèn)的時(shí)8:1:1),每次使用的是Eden與其中的一塊Survivor空間。當(dāng)回收時(shí),將存活的對(duì)象復(fù)制到另一塊Survivor空間上,最后清理掉Eden與survivor空間,這樣能使用的內(nèi)存空間就大大提高了。

如果剩下的Survivor空間不夠存放存活的對(duì)象,就需要依賴其他內(nèi)存來(lái)進(jìn)行分配擔(dān)保了,這些對(duì)象會(huì)直接通過(guò)分配擔(dān)保機(jī)制直接進(jìn)入老年代。


3.標(biāo)記-整理算法 (又稱標(biāo)記-壓縮算法)

標(biāo)記-整理算法時(shí)在標(biāo)記-清除算法上的一種改進(jìn)。整理不會(huì)改變對(duì)象排列的順序,只會(huì)縮小他們之間的間隙,把對(duì)象聚集到堆的一端。

標(biāo)記階段與前面的分析沒(méi)有什么區(qū)別,整理壓縮主要有以下三個(gè)步驟:

1.設(shè)定forwarding 指針

2.更新指針

3.移動(dòng)對(duì)象

標(biāo)記-整理算法

標(biāo)記-整理算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):java堆的利用得到進(jìn)一步的提高

缺點(diǎn):整理是一個(gè)移動(dòng)對(duì)象的過(guò)程,伴隨著對(duì)象的移動(dòng)以及指針的修改,這也是一筆不小的開銷


4.分代收集算法

這是現(xiàn)在主流的商業(yè)虛擬機(jī)采用的垃圾回收算法,其主要思想是將Java堆分為 新生代 與 老年代。

對(duì)新生代采用一般采用復(fù)制算法(大量的對(duì)象死亡,回收效率比較高),對(duì)老年代就必須使用標(biāo)記-清除或者標(biāo)記-整理算法來(lái)進(jìn)行回收


優(yōu)缺點(diǎn)

優(yōu)點(diǎn):效率明顯提升

缺點(diǎn):新生代GC所花費(fèi)的時(shí)間會(huì)增多,老年代GC會(huì)頻繁運(yùn)行。


現(xiàn)在常使用的垃圾收集器有如下幾種


常用的垃圾回收器

1.serial收集器? ? (新生代 單線程? 復(fù)制算法)

jdk1.3.1之前是新生代收集的唯一選擇

這是以一個(gè)單線程的收集器,它工作時(shí)會(huì)暫停其他所有的工作線程 也就是著名的 Stop- The -World



serial/serialOld收集器工作示意圖

優(yōu)點(diǎn):由于是單線程,所以沒(méi)有線程之間的切換開銷

缺點(diǎn):在其工作時(shí)會(huì)停止所有其他工作線程


2.ParNew 收集器? (serial的多線程版本) 新生代? 多線程? 復(fù)制算法


ParNew/serialOld收集器工作示意圖


在單CPU的環(huán)境下,其效率還不如Serial收集器

3.Parallel Scanvenge 收集器? (新生代 多線程? 復(fù)制算法)

這個(gè)收集器關(guān)注的不是系統(tǒng)停頓的時(shí)間,而是達(dá)到一個(gè)可以控制的吞吐量


4.Serial Old收集器 (老年代 單線程? 標(biāo)記-整理算法)


5.Paralle Old 收集器 (老年代 多線程 標(biāo)記-整理算法)

關(guān)注點(diǎn):吞吐量

6.CMS收集器 Concurrent Mark Sweep(老年代 多線程 標(biāo)記-清除算法)

關(guān)注點(diǎn):獲取最短回收停頓時(shí)間為目標(biāo)的收集器


CMS收集器工作示意圖

CMS收集器工作流程分為四個(gè)步驟

1.初始標(biāo)記//stop the world 標(biāo)記以下GC Roots能關(guān)聯(lián)到的對(duì)象

2.并發(fā)標(biāo)記// 標(biāo)記GC Roots之后的對(duì)象

3.重新標(biāo)記//stop the world 修正并發(fā)期間用戶程序繼續(xù)運(yùn)行產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄

4.并發(fā)清除

這是一款真正意義上的 并發(fā) 垃圾收集器

缺點(diǎn)

1.對(duì)CPU資源非常敏感

2.無(wú)法處理浮動(dòng)垃圾(垃圾收集的過(guò)程中,應(yīng)用程序運(yùn)行產(chǎn)生的其他垃圾)

3.因?yàn)闀r(shí)基于標(biāo)記-清除算法,所以依舊會(huì)產(chǎn)生大量的內(nèi)存碎片

7.科技的最前沿 G1收集器

G1的優(yōu)點(diǎn)有以下幾點(diǎn):

1.并行與并發(fā)

2.分代收集

3.基于標(biāo)記-整理算法,會(huì)對(duì)空間進(jìn)行進(jìn)一步的整合

4.Stop-The-World 的時(shí)間可以預(yù)測(cè)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容