垃圾回收算法
1. 标記-清除
- 過程:标記所有需要回收的對象,标記結束後,回收所有被标記的對象
- 缺點:效率低下,容易造成碎片
2. 複制
- 将記憶體空間分為兩部分,每次隻使用一部分,當一部分用盡,則将其所有對象複制到另一部分,并清理自身
- 特點:不産生碎片,但造成空間浪費
- 老年代将記憶體分為一個Eden 和兩個Survivor,每次使用一個Eden 和一個Survivor,回收時,将存活的對象複制到另一個Survivor,當待複制對象大于另一個Survivor 時,老年代進行擔保
3. 标記-整理
- 标記之後,将所有存活的對象移向另一端,清理其他對象
- 優點:解決了對象存活率高時,複制對象的壓力
4. 分代收集
根據年輕代[ 1, 2]、老年代[ 3]各自的特點,采用不同回收算法
垃圾回收器
Serial
單線程,在進行GC 時,需要停止其他的所有線程
ParNew
Serial 的多線程版本。但是在單線程環境下,由于線程開銷較大,效果不如Serial。但随着CPU 的增加,便可以顯現出優勢,預設線程數等于 CPU數。
Parallel Scavenge
多線程。可設定 1. 吞吐量(cpu 運作100分鐘,GC 使用1分鐘,Throughput = 99%),2. 最大GC 停頓時間(縮小GC 停頓時間,要以犧牲吞吐量和增加GC 頻率為代價)
年輕代與老年代的分界線
Serial Old
Serial 的老年代版本
CMS
擷取最短GC 停頓時間。基于标記-清除算法。
- 初始階段:主要負責标記GC Root能直接關聯的對象,速度快。
- 并發标記:從GC Root 開始繼續向下标記,耗時。
- 重新标記:統計在并發标記過程中發生變化的标記,時間長于 初始階段但小于 并發标記。
- 并發清除:清除老年代中的垃圾,耗時。
缺點:
- 産生碎片
- 浮動垃圾
- 對cpu 敏感
G1
可同時應用于年輕代和年老代的GC 器。基于标記-整理算法。使用時,堆記憶體布局發生變化,将堆分成性質不同的但大小相同的region,用以避免全局GC,建立可預測的停頓時間模型。每個 region對應一個 remembered set,當對象處于不同region,remember set 會進行記錄,即可保證不進行全局GC,也不會遺漏。
- 初始标記
- 并發标記
- 最終标記:将并發标記過程中發生變化的對象寫入線程remember set log,同時與remembered set 合并
- 篩選回收:通過比較region 的回收成本與價值,得到一個最好的回收方案
parallel old
老年代。标記-整理。吞吐量優先。
GC 時,程式邏輯是否繼續執行?
Serial、parnew 等=> stop the world