JVM系列之JVM垃圾回收算法相關(guān)知識
今天給大家繼續(xù)分享JVM垃圾回收算法相關(guān)知識。
JVM垃圾回收算法主要有標(biāo)記清除、復(fù)制算法、標(biāo)記整理、分代收集四種,下面來逐一介紹。
1、標(biāo)記清除(Mark-Sweep)
標(biāo)記清除作為最基礎(chǔ)的垃圾回收算法,其過程要經(jīng)歷兩個(gè)階段:標(biāo)記、回收。
標(biāo)記:遍歷內(nèi)存區(qū)域,標(biāo)記出待回收的對象。
回收:再次遍歷內(nèi)存區(qū)域,然后對已標(biāo)記的對象占用的內(nèi)存進(jìn)行回收。
缺點(diǎn):
- 需要遍歷兩次內(nèi)存區(qū)域,效率低。
- 因?yàn)镴VM存儲特點(diǎn)是邏輯上連續(xù),物理上可以不連續(xù),標(biāo)記清除算法可能產(chǎn)生大量內(nèi)存碎片,當(dāng)JVM需要一塊比較大的內(nèi)存空間的時(shí)候,而又找不到合適的內(nèi)存空間,就會觸發(fā)下一次的垃圾回收操作。
2、復(fù)制算法(Copy)
復(fù)制算法主要是解決標(biāo)記—清除算法遍歷的和產(chǎn)生內(nèi)存碎片的缺點(diǎn),在其基礎(chǔ)上進(jìn)行改進(jìn)而來的,它會將可用內(nèi)存按容量分為大小相等的兩塊,每次只能使用其中的一塊,當(dāng)正在使用的這一塊的內(nèi)存空間不滿足使用的時(shí)候,就會將還存活的對象復(fù)制到另外一塊空的內(nèi)存上面,然后再把當(dāng)前內(nèi)存空間一次清理掉。
復(fù)制算法在新生代中兩個(gè)幸存區(qū)(From 、To)的不停交換是最典型的用法。
新生代內(nèi)存空間占比為 8(Eden 伊甸園區(qū) ):1 (To Survivor):1 (Survivor From)。
優(yōu)點(diǎn)
- 內(nèi)存回收時(shí),不會產(chǎn)生內(nèi)存碎片
- 回收的時(shí)候只需移動棧頂指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡單
- 每次只對兩塊中的一塊內(nèi)存進(jìn)行回收,效率高
- 復(fù)制算法執(zhí)行后,空間時(shí)連續(xù)的。
缺點(diǎn):
一次性分配內(nèi)存只能用其中的一半,內(nèi)存的最大可利用率只有一半。
3、標(biāo)記整理(Mark-Compact)
標(biāo)記整理算法主要是針對老年代來設(shè)計(jì)的。
執(zhí)行過程:
- 標(biāo)記:對需要回收對象的進(jìn)行標(biāo)記。
- 整理:讓存活的對象,向內(nèi)存的一端移動,在整理的過程中,之前對象的在虛擬機(jī)棧中的引用地址也隨之發(fā)生改變,最后直接清理掉非存活對象的內(nèi)存空間。
優(yōu)點(diǎn):
- 沒有碎片化內(nèi)存產(chǎn)生(標(biāo)記清除算法比較)。
- 沒有了內(nèi)存利用率減半的消耗(復(fù)制算法比較)。
缺點(diǎn):
- 效率相比標(biāo)記復(fù)制算法稍低。
- 在整理存活對象過程中,因?yàn)榇婊顚ο笪恢命c(diǎn)變動,需要調(diào)整對象在虛擬機(jī)棧中的引用地址,同時(shí)需要全程暫停用戶線程,STW(Stop The World)。
4、分代收集算法
嚴(yán)格意義上來說分代收集不能算一種新的垃圾回收算法,分代收集其實(shí)只是根據(jù)對象的存活的時(shí)間的長短,將新生代和老年代針對不同的內(nèi)存區(qū)域,采取對應(yīng)的算法。目前市面上大多商用虛擬機(jī)都采用分代收集算法。
新生代:每次都有大量對象消亡,因?yàn)橛欣夏甏鳛閮?nèi)存擔(dān)保,比較采取復(fù)制算法。
老年代:對象存活時(shí)間長,可采用標(biāo)記整理、標(biāo)記清除算法。
5、三種垃圾回收算法對比
對比參數(shù) | 標(biāo)記清除 | 標(biāo)記整理 | 標(biāo)記復(fù)制 |
速度 | 中等 | 最慢 | 最快 |
空間開銷 | 少(會產(chǎn)生碎片) | 少(不會產(chǎn)生碎片) | 2倍開銷 |
移動對象 | 否 | 是 | 是 |
適合場景 | 老年代 | 老年代 | 新生代 |