騰訊云網(wǎng)站建設(shè)流程sem搜索引擎營(yíng)銷
目錄
一、分代收集理論
二、標(biāo)記-清除算法
三、標(biāo)記-復(fù)制算法?
四、標(biāo)記-整理算法
一、分代收集理論
分代收集理論建立在兩個(gè)分代假說之上:
1、弱分代假說:絕大多數(shù)對(duì)象都是朝生夕滅的。
2、強(qiáng)分代假說:熬過越多次垃圾收集過程的對(duì)象就越難以消亡。
這兩個(gè)分代假說共同奠定了多款垃圾收集器一致的設(shè)計(jì)原則:收集器應(yīng)該將Java堆劃分出不同的區(qū)域,然后將回收對(duì)象依據(jù)其年齡(年齡即對(duì)象熬過垃圾收集過程的次數(shù))分配到不同的區(qū)域之中存儲(chǔ)。
設(shè)計(jì)者一般至少會(huì)把Java堆劃分為新生代和老年代兩個(gè)區(qū)域。顧名思義,在新生代中,每次垃圾收集時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,而每次回收后存活的少量對(duì)象,將會(huì)逐步晉升到老年代中存放。
二、標(biāo)記-清除算法
算法分為“標(biāo)記”和“清除”兩個(gè)階段:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后,統(tǒng)一回收掉所有被標(biāo)記的對(duì)象。也可以反過來,標(biāo)記存活的對(duì)象,統(tǒng)一回收所有未被標(biāo)記的對(duì)象。
缺點(diǎn):
1、執(zhí)行效率不穩(wěn)定。如果Java堆中包含大量對(duì)象,而且其中大部分是需要被回收的,這時(shí)必須進(jìn)行大量標(biāo)記和清除的動(dòng)作,導(dǎo)致標(biāo)記和清除兩個(gè)過程的執(zhí)行效率都隨對(duì)象數(shù)量的增長(zhǎng)而降低。
2、內(nèi)存空間的碎片化問題。標(biāo)記、清除后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對(duì)象時(shí)無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作。
?
三、標(biāo)記-復(fù)制算法?
半?yún)^(qū)復(fù)制,將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對(duì)象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。如果內(nèi)存中多數(shù)對(duì)象都是存活的,這種算法會(huì)產(chǎn)生大量的內(nèi)存間復(fù)制的開銷,但對(duì)于多數(shù)對(duì)象都是可回收的情況,算法需要復(fù)制的就是占少數(shù)的存活對(duì)象,而且每次都是針對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,分配內(nèi)存時(shí)也就不用考慮有空間碎片的復(fù)雜情況,只要移動(dòng)棧頂指針,按順序分配即可。
優(yōu)點(diǎn)在于實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效,其缺點(diǎn)是將可用內(nèi)存縮小為原來的一半。
不過新生代中的對(duì)象(大概是98%)絕大部分都熬不過第一輪收集,因此并不需要按照1:1的比例來劃分新生代的內(nèi)存空間。
Appel式回收:?把新生代分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次分配內(nèi)存只使用Eden和其中一塊Survivor。發(fā)生垃圾搜集時(shí),將Eden和Survivor中仍然存活的對(duì)象一次性復(fù)制到另一塊Survivor空間上,然后直接清理掉Eden和已用過的那塊Survivor空間。HotSpot虛擬機(jī)默認(rèn)Eden和Survivor的大小比例為8:1。也即每次新生代中可用內(nèi)存空間為整個(gè)新生代容量的90%。任何人都沒有辦法百分百保證每次回收都只有不多于10%的對(duì)象存活,因此Appel式回收還有一個(gè)充當(dāng)罕見情況的“逃生門”的安全設(shè)計(jì),當(dāng)Survivor空間不足以容納一次Minor GC之后存活的對(duì)象時(shí),就需要依賴其他內(nèi)存區(qū)域(實(shí)際上大多數(shù)就是老年代)進(jìn)行分配擔(dān)保。
四、標(biāo)記-整理算法
標(biāo)記-復(fù)制算法在對(duì)象存活率較高時(shí)就要進(jìn)行較多的復(fù)制操作,效率將會(huì)降低。更關(guān)鍵的是,如果不想浪費(fèi)50%空間,就需要有額外的空間進(jìn)行分配擔(dān)保,以應(yīng)對(duì)算法中的極端情況。一般老年代不采取這種算法。
標(biāo)記-整理算法中的標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣,但后續(xù)步驟不是直接堆可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向內(nèi)存空間一段移動(dòng),然后直接清理掉邊界以外的內(nèi)存,核心是移動(dòng)。
如果移動(dòng)存活對(duì)象,尤其是在老年代這種每次回收都有大量對(duì)象存活區(qū)域,移動(dòng)存活對(duì)象并更新所有引用這些對(duì)象的地方將會(huì)是一種極為負(fù)重的操作,而且這種對(duì)象移動(dòng)的操作必須全程暫停用戶應(yīng)用程序才能進(jìn)行,被最初的虛擬機(jī)設(shè)計(jì)者描述為“Stop The World"。不過相較于標(biāo)記-清除算法,可以較好規(guī)避空間碎片化問題,此問題只能依賴更為復(fù)雜的內(nèi)存分配器和內(nèi)存訪問器來解決。
有一種方案,做法是讓虛擬機(jī)大多數(shù)時(shí)候采取標(biāo)記-清除算法,直到內(nèi)存空間碎片化程度大到影響對(duì)象分配時(shí),再采用標(biāo)記-整理算法收集一次,以獲得規(guī)整的內(nèi)存空間。例如基于標(biāo)記-清除算法的CMS收集器就是采納的此種方案。