Serial GC& ParNew GC& Parallel GC& CMS GC
- Serial垃圾收集器(串型回收)
-
- 1. Serial新生代收集器
- 2. Serial Old老年代收集器
- ParNew垃圾收集器(并行回收)
- Parallel垃圾收集器(并行回收)
- CMS垃圾收集器(并發回收)
Serial垃圾收集器(串型回收)
- Serial GC是最基礎, 曆史最悠久的垃圾收集器, Jdk1.3.1之前回收新生代的唯一選擇, 它是一個單線程的串行收集器, 當開始回收時, 将引起所有使用者線程 STW, 直到結束
- 在 JVM的 Client模式下, 它是預設收集器(Serial& Serial Old)
1. Serial新生代收集器
- 複制算法
2. Serial Old老年代收集器
- 标記-壓縮算法
- 在 JVM的 Server模式下, 1. 主要與 Parallel Scavenge(新年代并行回收)配合使用(Jdk14開始棄用). 2. 或作為 CMS(老年代并發回收)收集器的後備垃圾回收方案(Jdk14開始 CMS被棄用)

優點: 在單核 CPU環境中選擇它, 由于沒有線程間上下文切換的開銷, 性能比任何收集器都要好
- 開啟參數
後, 預設開啟 Serial Old老年代收集器, 也就是會同時生效
-XX:+UseSerialGC
ParNew垃圾收集器(并行回收)
- 如果 Serial GC是新年代的單線程收集器, 那麼 ParNew收集器, 則是 Serial收集器的多線程版本
- 針對新年代的回收
- 采用的複制算法, 同時垃圾回收時, 也會引起所有的使用者線程的 STW
- 除 Serial GC外, 目前隻有 ParNew GC能與 CMS收集器配合使用(Jdk14開始 CMS被棄用)
相對于 Serial GC優勢是在多核 CPU環境下, 可以充分利用處理性能, 更快的回收垃圾, 同時提升程式的吞吐量
- 開啟參數
, 表示新年代使用 ParNew收集器, 不影響老年代
-XX:+UseParNewGC
- 設定老年代為 CMS(并發收集器)
-XX:+UseConcMarkSweepGC
- 設定線程數
, 預設與 CPU的核數是相同的, 建議設定小于核數, 不建議設大于核數.
-XX:ParallelGCThreads=8
當核數大于8個 ParallelGCThreads=3 + (5 * cpu core / 8)
Parallel垃圾收集器(并行回收)
- HotSpot的新年代中, 除了 ParNew收集器是基于并行回收以外, Parallel Scavenge收集器同樣也采用了并行回收, 複制算法, 還有當垃圾回收時, 也會引起所有使用者線程的 STW
- Parallel Scavenge收集器是吞吐量優先的收集器, 差別于 ParNew收集器, 它具有自适應調節政策(如 新年代大小 Eden和 Survivor的比例, 還有晉升老年代的對象年齡等參數會被自動調整)
- 從 Jdk6開始提供了, 與它配套的老年代收集器 Parallel Old(它也是并行回收, 采用的算法是标記-壓縮算法, 同時也會引起 STW)
- (1) Parallel Scavenge和 Parallel Old的組合, 在 Jdk8的 Server模式下是預設收集器
- (2) 這個組合比較适合在高性能伺服器使用
* 注: 雖然可以搭配成 Parallel Scavenge + Serial Old, 不過此配套不如 ParNew + CMS, 是以如果想要使用 Parallel Scavenge就應該與 Parallel Old搭配
- 開啟新年代回收參數
, 開啟老年代回收參數 -XX:+UseParallelOldGC. 此兩參數隻要開啟一個, 另一個也會被自動開啟
-XX:+UseParallelGC
- 設定線程數
, 預設與 CPU的核數是相同的, 建議設定小于核數, 不建議設大于核數.
-XX:ParallelGCThreads=8
當核數大于8個 ParallelGCThreads=3 + (5 * cpu core / 8)
- 設定收集器最大停頓時間
(即 STW的時間, 機關為毫秒)
-XX:MaxGCPauseMillis=200
- 為了盡可能地将停頓時間控制在 MaxGCPauseMillis以内, 收集器在工作時會自動調整堆裡的相關參數
- 每次停頓時間越短對于使用者的體驗是越好的. 但一般停頓時間短意味着回收相對頻繁, 因而影響吞吐量. 作為吞吐量優先的收集器, 不宜與設定太小
- 該參數使用需謹慎
- 設定垃圾回收時間占總時間的比率(吞吐量)
-XX:GCTimeRatio=N
, 取值範圍是大于0, 且小于100的整數, 預設值為99, 也就是允許最大1%(即1 / ( 1 + N))的垃圾收集時間.
(*) 此參與
有一定沖突性. 是以在權衡參數時要抓住性能瓶頸
-XX:MaxGCPauseMillis
- 開啟 Parallel Scavenge收集器的自适應調節政策
-XX:+UseAdaptiveSizePolicy
(此參預設開啟)
(-) 自動調節新年代大小 Eden和 Survivor的比例, 還有晉升老年代的對象年齡等參數, 從此達到吞吐量, 暫停時間和記憶體占用之間的平衡
(-) 在調優比較困難的場合, 可以隻指定虛拟機的堆大小, 目标吞吐量 GCTimeRatio和停頓時間 MaxGCPauseMillis, 直接讓虛拟機自适應調節
CMS垃圾收集器(并發回收)
- Jdk5時 HotSpot推出了 CMS(Concurrent Mark-Sweep)收集器, 它是響應速度優先的低延遲垃圾收集器, 采用的算法是标記-清除算法, 還有依然存在 STW
- CMS垃圾回收4個階段:
- 初始标記(Initial-Mark)階段: 标記 GC Roots能夠直接關聯的對象. 此階段使用者線程會引起 STW, 直到初始标記完成
- 并發标記(Concurrent-Mark)階段: 周遊第1階段标記的可達對象, 進行根檢查後, 再标記為活躍的對象. 此階段是與使用者線程是并發進行的
- 重新标記(Remark)階段: 由于在并發标記階段中, 使用者線程和垃圾收集線程(标記階段)同時或交叉運作, 進而導緻了标記産生變動的那一部分的對象标記記錄做修正. 此階段使用者線程會引起 STW, 直到标記完成
- 并發清楚(Concurrent-Sweep)階段: 回收在标記階段判斷為不可達的對象, 由于用的标記-清除算法, 是以不需要移動存活對象, 是以也是并發進行的
- 以上階段中并發标記和并發清除階段是最耗費時間的, 但兩個都是并發回收(非獨占式), 是以整體的互動是低停頓的
- 優點: 并發回收, 低延遲
- 缺點:
- 由于采用的是标記-清除算法, 是以會産生記憶體碎片
- 在并發回收時, 雖然不會一次性停頓長時間影響互動體驗, 但是因為回收線程與使用者線程交替并發工作的, 是以吞吐量會下降
- 在并發标記階段, 對于浮動垃圾是有遺漏的, 無法及時回收隻能下次 GC時做标記, 并回收
* 注: 由于 CMS垃圾回收是并發進行的, 是以在回收過程中, 還應該確定應用程式有足夠的記憶體可用. 是以, CMS收集器不是等到老年代滿後再進行收集的, 而是當堆記憶體使用率達到某一門檻值時, 便開始進行回收. 要是運作期間預留的記憶體依然不夠, 就會出現一次 Concurrent Mode Failure, 然後虛拟機會自動采用 Serial Old收集器進行 Full GC
- 開啟 CMS垃圾收集器
後, 将自動開啟新年代的收集器
-XX:+UseConcMarkSweepGC
即: ParNew(Young區) + CMS(Old區) + Serial Old(當 Concurrent Mode Failure時用于觸發 Full GC)的組合
-XX:+UseParNewGC
- 設定堆記憶體使用率的門檻值
XX:CMSInitiatingOccupanyFraction=N
, 一旦到達該門檻值即觸發回收
(-) Jdk6之前預設值為68%, 之後92%
(*) 如果記憶體增長緩慢, 則可以設定一個稍大的值, 可以有效降低 CMS的觸發頻率. 反之, 如果應用程式記憶體增長很快, 則應該降低這個門檻值, 以避免頻繁觸發老年代串行收集器
- 開啟
當 Full GC後再對記憶體空間進行壓縮整理, 由于壓縮整理過程無法并發執行, 是以産生的問題是停頓時間變的更長(Jdk8開始此參已過時)
-XX:+UseCMSCompactAtFullCollection
- 設定次數
在上面的配置開啟的前提下, 執行了N次 Full GC後對記憶體空間進行壓縮整理(Jdk8開始此參已過時)
-XX:CMSFullGCsBeforeCompaction=N
- 設定 CMS的線程數
, 預設啟動的線程數是(
-XX:ParallelCMSThreads=2
; ParallelGCThreads是新年代 ParNew并行收集器的線程數
ParallelGCThreads + 3) / 4 = 2
如果您覺得有幫助,歡迎點贊哦 ~ 謝謝!!