一、算法的基本思想
1、標記-清除算法(Mark-Sweep)
分爲“標記”和“清除”兩個階段:首先標記出所有需要回收的對象,在標記完成後統一回收掉所有被標記的對象。
2、複製算法(Copying)
將可用內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用完了,就將還存活着的對象複製到另外一塊上面,然後再把已使用過的內存空間一次清理掉。
3、標記-整理算法(Mark-Compact)
和“標記-清除”算法類似,分爲“標記”和“清除”兩個階段:首先標記出所有需要回收的對象(該過程與“標記-清除”算法一樣),標記完成後,讓所有存活的對象都向一端移動,然後直接清理掉端邊界以外的內存。
4、分代收集算法(Generational Collection)
把Java堆分爲新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集算法。
二、四種算法的比較
名稱 | 優點 | 缺點 | |
---|---|---|---|
標記-清除算法(Mark-Sweep) | 後續算法的基礎 | 1、效率問題:效率低 2、空間問題:標記清除之後會產生大量的不連續的內存碎片(分配大對象時,沒有足夠連續內存會提前觸發另一次垃圾收集動作) | / |
複製算法(Copying) | 每次都是對半個區進行內存回收,沒有內存碎片問題; 實現簡單,運行高效 | 將內存縮小爲原來的一半; 執行較多複製操作,效率降低 | 當Survivor空間不夠時,需要依賴老年代進行分配擔保 |
標記-整理算法(Mark-Compact) | 沒有空間碎片問題且不會浪費50%的內存空間 | / | / |
分代收集算法(Generational Collection) | 能夠根據各個年代的特點採用最適當的收集算法 | / | 1、新生代中:GC後只有少量對象存活,選用複製算法 2、老年代中的對象存活率高,沒有額外空間來對它進行分配擔保,必須使用“標記-清除”或“標記-整理”算法 |