首頁(yè)技術(shù)文章正文

垃圾收集算法有哪些?圖文詳細(xì)介紹

更新時(shí)間:2021-10-22 來(lái)源:黑馬程序員 瀏覽量:

垃圾收集算法有標(biāo)記-清除算法、復(fù)制算法、標(biāo)記真理算法、分代收集算法四種,下面我們?cè)敿?xì)介紹。

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

最基礎(chǔ)的收集算法是標(biāo)記-清除算法,如同它的名字一樣,分為標(biāo)記和清除兩個(gè)階段。第一步標(biāo)記出所要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象。如何標(biāo)記已經(jīng)在上面說(shuō)過(guò)了,之所以說(shuō)它是最基本的垃圾收集算法,原因在于其他的算法也是基于這種思路并對(duì)其不足做以改進(jìn)得到的。

主要問(wèn)題有兩個(gè):

第一個(gè)是效率問(wèn)題,標(biāo)記和清除的效率都不高。

標(biāo)記清除算法

第二個(gè)是空間分配問(wèn)題,標(biāo)記清除后會(huì)產(chǎn)生大量的不連續(xù)的內(nèi)存空間,空間碎片太多可能會(huì)導(dǎo)致以后程序在運(yùn)行過(guò)程中需要給較大對(duì)象分配空間時(shí),無(wú)法找到足夠的內(nèi)存空間,而不得不提前進(jìn)行一次垃圾收集動(dòng)作。如圖所示,會(huì)產(chǎn)生大量的垃圾碎片,導(dǎo)致空間的利用率不高。


復(fù)制算法

為了解決效率問(wèn)題,一種稱為復(fù)制的收集算法出現(xiàn)了,它將可用內(nèi)存分為大小相等的兩塊,每次只使用其中的一塊,當(dāng)這一塊內(nèi)存區(qū)域用完了,就將還存活的對(duì)象復(fù)制到另一塊內(nèi)存中,然后再把已使用的空間一次性清理掉,這樣每次都是對(duì)半個(gè)區(qū)域進(jìn)行回收,內(nèi)存分配時(shí)也就不用考慮碎片等問(wèn)題了,只要移動(dòng)堆頂指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效。

只是這種做法將原來(lái)的內(nèi)存縮小為一半,代價(jià)太高了。

現(xiàn)在的商用虛擬機(jī)都采用這種方法來(lái)回收新生代,IBM專門研究表明,新生代中的對(duì)象98%都是"朝生夕死"的,所以并不需要按照1:1劃分內(nèi)存區(qū)域,而是將內(nèi)存分為一塊較大的區(qū)域給Eden和兩塊較小的區(qū)域給Survivor, 當(dāng)回收時(shí),將Eden和Survivor區(qū)中還存活的對(duì)象一次性復(fù)制到另一塊Survivor區(qū),然后將Eden和Survivor區(qū)進(jìn)行一次性清理。Hotspot區(qū)默認(rèn)的Eden和Survivor的比例為8:1,也就是說(shuō)新生代的可用內(nèi)存為90%,只有10%的內(nèi)存會(huì)被劃分為保留內(nèi)存。當(dāng)然,大多數(shù)情況下是98%,但我們不能保證每次回收的存活對(duì)象都小于10%,當(dāng)Survivor區(qū)不夠用時(shí),需要依賴其他區(qū)域進(jìn)行分配擔(dān)保。如果另外一塊Survivor區(qū)已經(jīng)不夠用了,對(duì)象可通過(guò)內(nèi)存擔(dān)保機(jī)制直接進(jìn)入到老年代。

復(fù)制算法

標(biāo)記整理算法

復(fù)制算法在存活對(duì)象比例比較高的情況下要進(jìn)行較多的復(fù)制操作,效率將會(huì)變低,更關(guān)鍵的是,如果不想浪費(fèi)50%的區(qū)域,則需要額外的空間進(jìn)行分配擔(dān)保,以應(yīng)對(duì)內(nèi)存中100%對(duì)象都存活的極端情況,所以老年代一般不選用這種算法。

根據(jù)老年代的特點(diǎn),有人提出了另一種標(biāo)記-整理算法,標(biāo)記過(guò)程與標(biāo)記-清除算法一致,但后續(xù)步驟不是對(duì)可回收對(duì)象直接進(jìn)行清理,而是讓所有存活對(duì)象都向一端移動(dòng),然后直接清理掉邊界外的對(duì)象。示意圖如下:

標(biāo)記整理算法

分代收集算法

當(dāng)前商用的垃圾收集器都采用的是分代垃圾回收,這種算法沒(méi)有什么新的思想,只是根據(jù)對(duì)象的存活周期將內(nèi)存分為幾塊,一般是將java堆分為新生代和老年代,這樣就可以根據(jù)各個(gè)代的對(duì)象特點(diǎn)選用最適當(dāng)?shù)幕厥账惴āT谛律看卫厥斩加写罅康膶?duì)象死去,只有少量存活,這樣就適合采用復(fù)制算法。只需要付出少量的對(duì)象復(fù)制成本就可以完成垃圾回收,而老年代因?yàn)榇婊盥矢?,沒(méi)有其他內(nèi)存進(jìn)行分配擔(dān)保,就必須使用標(biāo)記-清理或者標(biāo)記-整理進(jìn)行回收。

1. 分代分為年輕代和老年代,年輕代里頭又分為 Eden區(qū)和Survivor區(qū),通常默認(rèn)的比例為8:1:1, 每次只保留10%的空間用作預(yù)留區(qū)域,然后將90%的空間可以用作新生對(duì)象。

2. 每一次垃圾回收之后,存活的對(duì)象年齡對(duì)應(yīng)+1,當(dāng)經(jīng)歷15次還依然存活的對(duì)象,我們讓它直接進(jìn)入到老年代;

3. 另外一種進(jìn)入到老年代的方式是內(nèi)存擔(dān)保機(jī)制,也就是當(dāng)新生代的空間不夠的時(shí)候,對(duì)象直接進(jìn)入到老年代;

4. 新生代的垃圾回收叫Minor GC,老年代的叫Full GC。

添加QQ(注意~~添加好友界面,選擇找人):435946716,【免費(fèi)】獲取《JVM核心教程:JVM從門到精通_JVM虛擬機(jī)底層原理深入教程》全套視頻教程+配套資料。


猜你喜歡

Java中的垃圾回收機(jī)制是什么?哪些對(duì)象會(huì)被回收?

JVM組成部分和作用詳細(xì)介紹

黑馬程序員JavaEE高手班課程

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!