當(dāng)前Java垃圾回收主要有三種算法,然后根據(jù)不同情況,對三種算法進行結(jié)合,進行分代收集。
一. 標(biāo)記-清除算法
1. 標(biāo)記-清除(Mark-Sweep)分為兩個階段:首先標(biāo)記出所有需要回收的對象,在標(biāo)記完成之后統(tǒng)一回收被標(biāo)記的對象。
2. 它是最基礎(chǔ)的算法,后序的算法都是基于該算法改進的。
3. 有兩個不足:第一,標(biāo)記和清除效率都不高;第二,清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片。
二. 復(fù)制算法
1. 復(fù)制算法Copying,將內(nèi)存分為大小相同的兩塊, 每次只使用其中一塊,當(dāng)這一塊用完時,就將還存活的對象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存一次清理掉。
2. 每次是使用一般的內(nèi)存,效率不高,但不會有內(nèi)存碎片。
3. 改進:因為新生代的對象98%都是朝生夕死,所以不需要按照1:1進行分配。將內(nèi)存分為一塊較大的Eden和兩塊較小的Survivor空間,每次使用Eden和一塊Survivor空間,當(dāng)回收時將Eden和Survivor中還存活著的對象一次性復(fù)制到另外一塊Survivor空間上,最后清理掉Eden和剛才用過的Survivor空間。HotSpot默認(rèn)Eden:Survivor=8:1。當(dāng)Survivor空間不夠用時,需要借助老年代進行分配擔(dān)保。
三. 標(biāo)記-整理算法
1. 復(fù)制算法在對象存活率較高時效率會低下。
2. 根據(jù)老年代的特點,標(biāo)記-整理(Mark-Compact)算法與標(biāo)記清除的標(biāo)記過程一樣,但在清除階段是讓所有存活對象都移向一端,然后直接清理掉端邊界以外的內(nèi)存。
四. 分代收集算法
1. 當(dāng)前商業(yè)虛擬機的垃圾收集都采用分代收集算法,將Java堆分為新生代和老年代,根據(jù)每個代的不同,新生代因為每次垃圾收集都會有大量對象死去,所以采用復(fù)制算法。老年代存活率較高且沒有額外空間進行分配擔(dān)保,所以使用標(biāo)記-清除或者標(biāo)記-整理算法進行垃圾回收。