前面在java垃圾收集算法中講過垃圾收集算法中的分代收集器,今天看了一個視頻發(fā)現(xiàn)里面將的也很不錯,所以決定再總結(jié)一下。
我們知道,在分代收集算法中堆空間被分為新生代和老年代。因為新生代中對象的存活率比較低,所以一般采用復(fù)制算法,老年代的存活率一般比較高,一般使用”標(biāo)記-清理”或者”標(biāo)記-整理”算法進(jìn)行回收。

上面的這個圖已經(jīng)很清楚的將堆的分區(qū)展現(xiàn)出來了。
下面我們來看看具體的算法過程。
新創(chuàng)建的對象一般放在新生代的Enden區(qū),如下圖所示。

上面對象中,綠色代表的是"存活對象",灰色的代表的是"待回收對象"。當(dāng)Enden中被使用完的時候,就會發(fā)生新生代GC,也就是Minor GC,如下圖。

首先會把存活對象復(fù)制到Survivor1中。

然后把Enden清空

移動到Survivor1空間后,設(shè)置對象年齡(Age)為1

這樣第一次GC就完成了。
當(dāng)Enden區(qū)再次被使用完的時候,就會再次進(jìn)行GC操作。

上面Enden和Survivor1中,綠色表示存活對象,回收表示"待回收對象",因為在堆內(nèi)存使用分配的過程中,也會不斷有對象變得引用不可達(dá)。
再次GC的過程中,跟上面一樣,將Enden區(qū)和Survivor1中的存活對象復(fù)制到Survivor2中。需要注意的是目前還是處于新生代的GC,因為新生代分為Enden、Survivor1、Survivor2三個區(qū),使用的其實就是復(fù)制算法。

接著將Enden和Survivor1進(jìn)行清空

然后將Enden中復(fù)制到Survivor2中的對象年齡設(shè)置為1,將Survivor1中復(fù)制到Survivor2中的對象年齡加1

這樣新生代第二次GC就完成了。當(dāng)Enden再一次被使用完的時候,就會發(fā)生第三次GC操作了。

下面基本重復(fù)上面的思路了,首先將Enden和Survivor2中的存活對象復(fù)制到Survivor1中。

然后將Enden和Survivor2進(jìn)行清空

然后將Enden中復(fù)制到Survivor1中的對象年齡設(shè)置為1,將Survivor2中復(fù)制到Survivor1中的對象年齡加1

后面的操作基本都是重復(fù)的,那什么時候會進(jìn)入老年代呢?從上面看到,如果對象在GC過程中沒有被回收,那么它的對象年齡(Age)會不斷的增加,對象在Survivor區(qū)每熬過一個Minor GC,年齡就增加1歲,當(dāng)它的年齡到達(dá)一定的程度(默認(rèn)為15歲),就會被移動到老年代,這個年齡閥值可以通過-XX:MaxTenuringThreshold設(shè)置。

視頻鏈接:Garbage collection in Java, with Animation and discussion of G1 GC
新聞熱點
疑難解答