JVM G1垃圾回收算法簡要介紹
G1的特點
- 能夠像CMS垃圾回收算法一樣並發操作應用線程(潛台詞:多核)
- 無需太長時間即可壓縮空閑內存空間(潛台詞:不會引起太多的GC停頓時間)
- 盡可能地讓GC時長可控
- 不希望犧牲過多的吞吐量
- 不希望因此耗費大量更多的Heap空間
G1的優勢
G1作為CMS的長期替代品,有若干點優勢:
- G1是一個壓縮收集器,提供足夠強的壓縮來完全避免狹小的內存分配
- 依賴Regions概念,大大簡化收集器邏輯,大部分情況下規避潛在的內存碎片問題
- 比CMS的GC停頓時長更加可預測,並允許用戶指定停頓時長
G1的收集步驟
Phase 1: Concurrent Global Marking. 並發掃描一遍之后,G1知道了哪些Region里大部分是空的(即大部分是可回收的對象),G1把收集和壓縮操作集中於此,因此得名Garbage First.
Phase 2: Evacuation. 並發地將一個或多個Region的資源拷貝至新的Region,壓縮內存、拷貝、釋放已拷貝完成的Region. 與此相比,CMS沒有壓縮內存(去除碎片)這一步,ParallelOld垃圾收集只進行全堆壓縮.
細節:G1會估算Region的回收時間,以計算在用戶指定時間內可回收多少(量力而行),因此G1不是『實時』收集器 :)
G1的建議使用場景
擁有較大Heap空間(6GB及以上)、低停頓時長(0.5ms以內)要求的應用。
現在使用ParallelGC或CMS的應用,如果存在以下問題,可以考慮切換至G1:
- Full GC過於頻繁、停頓時間過長的應用
- 對象分配比例經常發生劇變的應用
- 回收或壓縮時間太長的應用(高於0.5s到1s)
如果使用ParallelGC或CMS沒有發現以上現象,可以不必急於切換到G1,新版JVM仍然支持舊的垃圾回收算法。
G1的注意事項
若從ParallelOldGC或CMS切換至G1,很可能會發現JVM運行內存變大了。這很大程度上要歸因於 用於審計的兩個數據結構『Remembered Sets』和『Collection Sets』
- 『Remembered Sets』每個Region都有一個,用於記錄該Region中的對象引用,給G1提供並行獨立收集各Region內存的可能性,它帶來的負面影響不超5%
- 『Collection Sets』記錄被收集的Region,它內部的所有數據會被收集干凈,它帶來的負面影響不超1%