1. 程式人生 > >垃圾回收2:垃圾收集演算法

垃圾回收2:垃圾收集演算法

垃圾收集演算法

標記-清除演算法

分為“標記”和“清除”兩個階段。首先標記出所有需要回收的物件,在標記完成後統一回收所有被標記的物件。 存在以下兩個問題:

  • 效率問題
  • 空間問題:標記清除後會產生大量不連續的碎片

複製演算法

將記憶體劃分為大小相等的兩塊,每次只使用其中一塊,當這一塊記憶體用完了就將還存活的物件複製到另一塊上面,然後再把使用過的記憶體空間進行一次清理。

現在的商業虛擬機器都採用這種收集演算法來回收新生代,但是並不是將新生代劃分為大小相等的兩塊,而是分為一塊較大的 Eden 空間和兩塊較小的 Survivor 空間,每次使用 Eden 空間和其中一塊 Survivor。在回收時,將 Eden 和 Survivor 中還存活著的物件一次性複製到另一塊 Survivor 空間上,最後清理 Eden 和使用過的那一塊 Survivor。

HotSpot 虛擬機器的 Eden 和 Survivor 的大小比例預設為 8:1,保證了記憶體的利用率達到 90%。如果每次回收有多於 10% 的物件存活,那麼一塊 Survivor 空間就不夠用了,此時需要依賴於老年代進行分配擔保,也就是借用老年代的空間儲存放不下的物件。

標記-整理

根據老年代的特點特出的一種標記演算法,標記過程仍然與“標記-清除”演算法一樣,但後續步驟不是直接對可回收物件回收,而是讓所有存活的物件向一端移動,然後直接清理掉端邊界以外的記憶體。

分代收集

現在的商業虛擬機器採用分代收集演算法,它根據物件存活週期將記憶體劃分為幾塊,不同塊採用適當的收集演算法。

一般將堆分為新生代和老年代。在新生代中,每次收集都會有大量物件死去,所以可以選擇複製演算法,只需要付出少量物件的複製成本就可以完成每次垃圾收集。而老年代的物件存活機率是比較高的,而且沒有額外的空間對它進行分配擔保,所以我們必須選擇標記-清除標記-整理演算法進行垃圾收集。