7種JVM垃圾收集器特點,優劣勢、及使用場景
本系列會持續更新 。

今天繼續JVM的垃圾回收器詳解,如果說垃圾收集演算法是JVM記憶體回收的方法論,那麼垃圾收集器就是記憶體回收的具體實現。
一、常見的垃圾收集器有3類

1.新生代的收集器包括
Serial
PraNew
Parallel Scavenge
2.老年代的收集器包括
Serial Old
Parallel Old
CMS
3.回收整個Java堆(新生代和老年代)
G1收集器
今天我們詳細談談以上7種垃圾收集器的優劣勢和使用場景。

新生代垃圾收集器
1.Serial序列收集器-複製演算法
Serial收集器是新生代單執行緒收集器,優點是簡單高效,算是最基本、發展歷史最悠久的收集器。它在進行垃圾收集時,必須暫停其他所有的工作執行緒,直到它收集完成。

Serial收集器依然是虛擬機器執行在Client模式下預設新生代收集器,對於執行在Client模式下的虛擬機器來說是一個很好的選擇。
2.ParNew收集器-複製演算法
ParNew收集器是 新生代並行收集器 ,其實就是Serial收集器的多執行緒版本。

除了使用多執行緒進行垃圾收集之外,其餘行為包括Serial收集器可用的所有控制引數、收集演算法、Stop The Worl、物件分配規則、回收策略等都與Serial 收集器完全一樣。
3.Parallel Scavenge(並行回收)收集器-複製演算法
Parallel Scavenge收集器是新生代並行收集器,追求高吞吐量,高效利用 CPU。
該收集器的目標是達到一個可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用於執行使用者程式碼的時間與CPU總消耗時間的比值,即 吞吐量=執行使用者程式碼時間/(執行使用者程式碼時間+垃圾收集時間)
停頓時間越短就越適合需要與使用者互動的程式,良好的響應速度能提升使用者體驗,而高吞吐量則可用高效率地利用CPU時間,儘快完成程式的運算任務,主要適合在後臺運算而不需要太多互動的任務。
老年代垃圾收集器
1.Serial Old 收集器-標記整理演算法
Serial Old是Serial收集器的老年代版本,它同樣是一個單執行緒(序列)收集器,使用標記整理演算法。這個收集器的主要意義也是在於 給Client模式下的虛擬機器使用 。
如果在Server模式下,主要兩大用途:
(1)在JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用
(2)作為CMS收集器的後備預案,在併發收集發生Concurrent Mode Failure時使用
2.Parallel Old 收集器-標記整理演算法
Parallel Old 是Parallel Scavenge收集器的老年代版本,使用多執行緒和“標記-整理”演算法。這個收集器在1.6中才開始提供。
3.CMS收集器-標記整理演算法
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。
目前很大一部分的Java應用集中在網際網路站或者B/S系統的服務端上,這類應用尤其重視伺服器的響應速度,希望系統停頓時間最短,以給使用者帶來較好的體驗。CMS收集器就非常符合這類應用的需求。
CMS收集器是基於“標記-清除”演算法實現的, 它的運作過程相對前面幾種收集器來說更復雜一些,整個過程分為4個步驟:
(1)初始標記;
(2)併發標記;
(3)重新標記;
(4)併發清除。
其中,初始標記、重新標記這兩個步驟仍然需要“Stop The World”

CMS收集器主要優點 :
併發收集;
低停頓。
CMS三個明顯的缺點:
(2)CMS收集器無法處理浮動垃圾,可能出現“Concurrent Mode Failure”失敗而導致另一次Full GC的產生。在JDK1.5的預設設定下,CMS收集器當老年代使用了68%的空間後就會被啟用;
(2)CMS收集器無法處理浮動垃圾,可能出現“Concurrent Mode Failure”失敗而導致另一次Full GC的產生。在JDK1.5的預設設定下,CMS收集器當老年代使用了68%的空間後就會被啟用。
(3)CMS是基於“標記-清除”演算法實現的收集器,手機結束時會有大量空間碎片產生。空間碎片過多,可能會出現老年代還有很大空間剩餘,但是無法找到足夠大的連續空間來分配當前物件,不得不提前出發FullGC。
新生代和老年代垃圾收集器
1.G1收集器-標記整理演算法
JDK1.7後全新的回收器, 用於取代CMS收集器。
G1收集器的優勢:
獨特的分代垃圾回收器,分代GC: 分代收集器, 同時兼顧年輕代和老年代;
使用分割槽演算法, 不要求eden, 年輕代或老年代的空間都連續;
並行性: 回收期間, 可由多個執行緒同時工作, 有效利用多核cpu資源;
空間整理: 回收過程中, 會進行適當物件移動, 減少空間碎片;
可預見性: G1可選取部分割槽域進行回收, 可以縮小回收範圍, 減少全域性停頓。
G1收集器的運作大致可劃分為一下步驟:

G1收集器的階段分以下幾個步驟:
1、初始標記(它標記了從GC Root開始直接可達的物件);
2、併發標記(從GC Roots開始對堆中物件進行可達性分析,找出存活物件);
3、最終標記(標記那些在併發標記階段發生變化的物件,將被回收);
4、篩選回收(首先對各個Regin的回收價值和成本進行排序,根據使用者所期待的GC停頓時間指定回收計劃,回收一部分Region)。
二、JVM垃圾收集器總結
本文主要介紹了JVM中的垃圾回收器,主要包括序列回收器、並行回收器以及CMS回收器、G1回收器。他們各自都有優缺點,通常來說你需要根據你的業務,進行基於垃圾回收器的效能測試,然後再做選擇。下面給出配置回收器時,經常使用的引數:
-XX:+UseSerialGC:在新生代和老年代使用序列收集器
-XX:+UseParNewGC:在新生代使用並行收集器
-XX:+UseParallelGC :新生代使用並行回收收集器,更加關注吞吐量
-XX:+UseParallelOldGC:老年代使用並行回收收集器
-XX:ParallelGCThreads:設定用於垃圾回收的執行緒數
-XX:+UseConcMarkSweepGC:新生代使用並行收集器,老年代使用CMS+序列收集器
-XX:ParallelCMSThreads:設定CMS的執行緒數量
-XX:+UseG1GC:啟用G1垃圾回收器
覺得不錯請點贊支援下。
----end----
我是mike,10年+程式設計師。曾先後就職於淘寶、盛大、百度、攜程 ,歷任高階研發工程師、研發經理、架構師、事業部CTO。堅持寫文1年多,原創內容接近400篇,目前粉絲總數7萬+,主要分享:BAT面試、Java架構、招聘資訊等內容。進群 179961551 獲取以下資料~
