1. 程式人生 > >7種JVM垃圾收集器特點,優劣勢、及使用場景

7種JVM垃圾收集器特點,優劣勢、及使用場景

7種JVM垃圾收集器特點,優劣勢、及使用場景


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

常見的垃圾收集器有3類:

  1. 新生代的收集器包括:
  • Serial
  • PraNew
  • allel Scavenge
  1. 老年代的收集器包括:
  • Serial Old
  • Parallel Old
  • CMS
  1. 回收整個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三個明顯的缺點:
  • CMS收集器對CPU資源非常敏感。CPU個數少於4個時,CMS對於使用者程式的影響就可能變得很大,為了應付這種情況,虛擬機器提供了一種稱為“增量式併發收集器”的CMS收集器變種。
  • CMS收集器無法處理浮動垃圾,可能出現“Concurrent Mode Failure”失敗而導致另一次Full GC的產生。在JDK1.5的預設設定下,CMS收集器當老年代使用了68%的空間後就會被啟用
  • 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垃圾回收器