jvm 的垃圾回收算法
1.標(biāo)記-清除算法
標(biāo)記出所有需要回收的對象,在標(biāo)記完成后,統(tǒng)一回收掉所有被標(biāo)記的對象,也可以反過來,標(biāo)記出所有存活的對象,在標(biāo)記完成后,統(tǒng)一回收所有未被標(biāo)記的對象,標(biāo)記過程就是對象是否屬于垃圾的判定過程,基于可達(dá)性分析算法判斷對象是否可以回收;
標(biāo)記后,對所有被標(biāo)記的對象進(jìn)行回收;
缺點(diǎn):
等待被回收對象的“標(biāo)記”過程在上文已經(jīng)提到過,如果在被標(biāo)記后直接對對象進(jìn)行清除,會帶來另一個新的問題——內(nèi)存碎片化。如果下次有比較大的對象實(shí)例需要在堆上分配較大的內(nèi)存空間時,可能會出現(xiàn)無法找到足夠的連續(xù)內(nèi)存而不得不再次觸發(fā)垃圾回收。
2.復(fù)制算法(Java堆中新生代的垃圾回收算法)
復(fù)制算法是標(biāo)記-復(fù)制算法的簡稱,將可用內(nèi)存按容量分為大小相等的兩塊,每次只使用其中一塊,當(dāng)這一塊的內(nèi)存用完了,就將還存活的對象復(fù)制到另外一塊內(nèi)存上,然后再把已使用過的內(nèi)存空間一次清理掉;
此GC算法實(shí)際上解決了標(biāo)記-清除算法帶來的“內(nèi)存碎片化”問題。首先還是先標(biāo)記處待回收內(nèi)存和不用回收的內(nèi)存,下一步將不用回收的內(nèi)存復(fù)制到新的內(nèi)存區(qū)域,這樣舊的內(nèi)存區(qū)域就可以全部回收,而新的內(nèi)存區(qū)域則是連續(xù)的。它的缺點(diǎn)就是會損失掉部分系統(tǒng)內(nèi)存,因為你總要騰出一部分內(nèi)存用于復(fù)制。
新的對象實(shí)例被創(chuàng)建的時候通常在Eden空間,發(fā)生在Eden空間上的GC稱為Minor GC,當(dāng)在新生代發(fā)生一次GC后,會將Eden和其中一個Survivor空間的內(nèi)存復(fù)制到另外一個Survivor中,如果反復(fù)幾次有對象一直存活,此時內(nèi)存對象將會被移至老年代。可以看到新生代中Eden占了大部分,而兩個Survivor實(shí)際上占了很小一部分。這是因為大部分的對象被創(chuàng)建過后很快就會被GC(這里也許運(yùn)用了是二八原則)。
3.標(biāo)記-壓縮算法(或稱為標(biāo)記-整理算法,Java堆中老年代的垃圾回收算法)
對于新生代,大部分對象都不會存活,所以在新生代中使用復(fù)制算法較為高效,而對于老年代來講,大部分對象可能會繼續(xù)存活下去,如果此時還是利用復(fù)制算法,效率則會降低。標(biāo)記-壓縮算法首先還是“標(biāo)記”,標(biāo)記過后,將不用回收的內(nèi)存對象壓縮到內(nèi)存一端,此時即可直接清除邊界處的內(nèi)存,這樣就能避免復(fù)制算法帶來的效率問題,同時也能避免內(nèi)存碎片化的問題。老年代的垃圾回收稱為“Major GC”。
優(yōu)點(diǎn):
1、不會像復(fù)制算法那樣劃分兩個區(qū)域,提高了空間利用率;
2、不會產(chǎn)生不連續(xù)的內(nèi)存碎片;
缺點(diǎn):效率問題,除了像標(biāo)記-清除算法的標(biāo)記過程外,還多了一步整理過程,效率變低;
4、分代收集算法
在一般虛擬機(jī)的垃圾收集都是采用“ 分代收集 ”算法;
根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊,一般把java堆分為新生代和老年代,JVM根據(jù)各個年代的特點(diǎn)采用不同的收集算法;
新生代中,每次進(jìn)行垃圾回收都會發(fā)現(xiàn)大量對象死去,只有少量存活,因此采用復(fù)制算法,只需要付出少量存活對象的復(fù)制成本就可以完成收集;
老年代中,因為對象存活率較高,采用標(biāo)記-清理、標(biāo)記-整理算法來進(jìn)行回收;
總結(jié)
以上是生活随笔為你收集整理的jvm 的垃圾回收算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM内存相关的核心参数?
- 下一篇: JVM怎么判断对象是否存活