Java虛擬機(JVM)中的垃圾收集算法主要分為以下幾種:
- 標記-清除算法(Mark-Sweep)
- 復制算法(Copying)
- 標記-整理算法(Mark-Compact)
- 分代收集算法(Generational Collecting)
- G1垃圾收集器(Garbage-First)
- ZGC(Z Garbage Collector)
- Shenandoah垃圾收集器
1. 標記-清除算法(Mark-Sweep)
原理:
- 標記階段:從根對象開始,遍歷整個對象圖,標記所有被引用的對象。
- 清除階段:遍歷整個堆,清除未被標記的對象,釋放其內存。
優點:
- 直觀,簡單,適用于任何對象圖。
缺點:
- 內存碎片化嚴重,因為清除階段并不移動對象,導致堆中可能有大量不連續的可用空間,產生內存碎片。
- 標記和清除階段都需要掃描整個堆,效率較低。
- GC的時候需要停止整個應用程序,用戶體驗不好
2. 復制算法(Copying)
原理:
- 將堆分為兩個等大的區域,每次只使用其中一個。當活動對象達到一定比例時,將活動對象復制到另一個區域,然后清空當前區域。
- 復制過程中保留活動對象,并保持對象的相對位置不變。
優點:
- 沒有內存碎片問題,因為每次都會在一個新的區域中重新排列對象。
- 分配速度快,只需分配指針移動。
缺點:
- 需要兩倍的內存空間,因為要維持兩個區域。
- 對于存活率高的對象,復制成本高。
- 只適用于存活對象少的情況/頻繁消亡的情況(非常適合新生代)
3. 標記-整理算法(Mark-Compact)
原理:
- 標記階段:與標記-清除算法相同。
- 整理階段:將所有存活的對象壓縮到堆的一端,保持空間的連續性,然后清理邊界以外的內存。
優點:
- 消除內存碎片問題,因為對象都被壓縮到一端,剩余空間連續。
- 在整理階段減少了內存分配的復雜度,消除了復制算法翻倍消耗內存的缺點。
缺點:
- 整理階段涉及大量對象移動,可能會導致較高的性能開銷。
- 效率其實不如復制算法,在對象移動后,其他地方引用了該對象的話,還需要同步修改對象的引用地址
前面所有這些算法中,并沒有一種算法可以完全替代其他算法,它們都具有自己獨特的優勢和特點。分代收集算法應運而生。
分代收集算法:是基于這樣一個事實:不同的對象的生命周期是不一樣的。因此,不同生命周期的對象可以采取不同的收集方式,以便提高回收效率。一般是把Java堆分為新生代和老年代,這樣就可以根據各個年代的特點使用不同的回收算法,以提高垃圾回收的效率。
在Java程序運行的過程中,會產生大量的對象,其中有些對象是與業務信息相關,比如Http請求中的Session對象、線程、Socket連接,這類對象跟業務直接掛鉤,因此生命周期比較長。但是還有一些對象,主要是程序運行過程中生成的臨時變量,這些對象生命周期會比較短,比如:string對象,由于其不變類的特性,系統會產生大量的這些對象,有些對象甚至只用一次即可回收。
4. 分代收集算法(Generational Collecting)
詳情請移步堆篇章
JVM之【運行時數據區2——堆】
原理:
- 將堆劃分為不同的代(一般為年輕代和老年代)。
- 年輕代使用復制算法,老年代使用標記-清除或標記-整理算法。
- 依據“弱分代假說”,大多數對象很快就會死亡。
優點:
- 優化了垃圾收集的效率,因為年輕代對象存活率低,收集速度快。
- 減少了老年代垃圾收集的頻率。
缺點:
- 需要復雜的調優工作,以確定代大小和收集策略。
- 在年輕代和老年代之間的對象移動可能會產生額外的開銷。
5. 分區收集算法/G1垃圾收集器(Garbage-First)
- 一般來說,在相同條件下,堆空間越大,一次Gc時所需要的時間就越長,有關GC產生的停頓也越長。為了更好地控制GC產生的停頓時間,將一塊大的內存區域分割成多個小塊,根據目標的停頓時間,每次合理地回收若干個小區間,而不是整個堆空間,從而減少一次GC所產生的停頓。
- 分代算法將按照對象的生命周期長短劃分成兩個部分,分區算法將整個堆空間劃分成連續的不同小區間。
- 每一個小區間都獨立使用,獨立回收。這種算法的好處是可以控制一次回收多少個小區間。
原理:
- 將堆分為多個區域(regions),分別處理,優先回收垃圾最多的區域。
- 結合了標記-清除和標記-整理算法,適用于大堆的垃圾收集。
優點:
- 低暫停時間,適合大堆應用。
- 可以并行和并發進行垃圾收集,提升性能。
缺點:
- 相對較復雜的實現和調優。
- 在某些情況下,性能可能不如其他收集器。
6.Shenandoah垃圾收集器
原理:
- 以并發標記和并發整理為基礎,最小化垃圾收集對應用線程的影響。
- 使用并發壓縮技術減少停頓時間。
優點:
- 低停頓時間,適合延遲敏感應用。
- 高效處理大堆內存。
缺點:
- 復雜的實現和調優。
- 性能可能受限于特定的硬件和JVM版本。
總結
不同垃圾收集算法和垃圾收集器各有優缺點,應根據具體應用需求和硬件環境選擇合適的垃圾收集策略。標記-清除和復制算法比較基礎,適用于小型或簡單應用;分代收集算法適用于大多數常規應用;G1、Shenandoah更適合大內存、低延遲的高性能應用。