在回收垃圾對象以前,垃圾收集器須要確認哪些對象「存活」和那些對象應該被回收算法
引用計數是最古老的一種算法,在微軟的COM組件技術,Adobe的ActionScript3中都有使用。實現就是:對於一個對象A,只要任何一個對象引用了A,則A的引用計數器就加1;當引用失效時,引用計數器就減1;當一個對象的計數器值爲0時,則對象A則不可能再被使用。性能
引用計數的缺點在於:優化
在主流的商用程序語言的主流實現中,都是經過可達性分析來判斷一個對象是否應該存活的。其基本思想就是經過一系列的稱爲「GC Roots」的對象做爲根節點,從這些節點開始向下搜索,搜索所走過的路徑稱爲「引用鏈」。當一個對象到「GC Roots」沒有任何的引用鏈相連時,則證實此對象能夠被回收。code
在Java虛擬機中,可做爲GC Roots的對象包括如下幾種:對象
擴展:Java語言的四種引用類型:強引用,軟引用,弱引用,虛引用ip
標記清除算法將垃圾回收分爲標記
,清除
兩個階段。在標記
階段,標記全部從根節點開始的可達對象,此時未標記的對象即爲垃圾對象,等待回收。在清除
階段,清除全部的未標記對象。內存
標記清除的缺點在於:虛擬機
複製算法的核心思想是將原有的內存空間分爲兩塊,每次只使用其中的一塊,在垃圾回收時,將存活的對象複製到另外一塊未被使用的空間,以後清除原來使用的空間中的全部對象。it
複製算法的優勢:io
缺點:
在Java虛擬機新生代串行垃圾回收器中,使用了複製算法的思想。新生代被分爲eden
,from
,to
三個內存空間。其中from
,to
是兩塊大小至關,地位相同且可進行角色互換的空間,也統稱爲survivor
空間。
相比於複製算法存活對象少,垃圾對象多的狀況,標記壓縮算法一般用於大部分對象都是存活對象的狀況(老年代的回收算法)。它在標記清除
算法的基礎上作了一些優化,在標記存活對象後,將全部的對象壓縮到內存的一端,而後再清除邊界外的全部空間。
優勢:
由於只是比標記清除
多了一個壓縮的步驟,因此也被稱爲標記清除壓縮算法(MarkSweepCompact)
在上面的一系列算法中,並無哪一種算法能夠徹底的替代其餘的算法。它們各自具有本身獨特的優點和特色。所以,將內存區間根據對象的特色分紅幾塊,每塊使用不一樣的回收算法,以提升垃圾回收效率,這就是分代算法。
在Java虛擬機中,全部的新建對象都會優先存放在新生代
內存空間中,對於新生代內存空間中的對象,很容易就被回收,所以新生代適合複製算法。當一個對象通過幾回回收後仍然存活,該對象就會被放入老年代
內存空間,在老年代內存空間的對象,通過幾回垃圾回收後仍然存活的機率一般很大,根據分代的思想,老年代適合標記壓縮或標記清除算法。