JVM:這是一份全面 & 詳細的 常見垃圾收集器 匯總攻略

  • 2019 年 10 月 25 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/carson_ho/article/details/102675617

前言

  • 垃圾收集器 是 垃圾收集演算法 的具體實現
  • 本文將對市面上常見的垃圾收集器類型進行講解,希望你們會喜歡

在接下來的日子,我會推出一系列講解JVM的文章,具體如下;

垃圾收集器類型

  • 垃圾收集器 是 垃圾收集演算法 的具體實現
  • 現在主流的垃圾收集器有 7 種:
  • 我們會根據需求場景的不同,選擇不同特點的垃圾收集器

下面我會詳細介紹。

1. Serial收集器

1.1 定義

最基本、發展歷史最長的垃圾收集器

1.2 優點

  • 並發收集 在進行垃圾收集時,必須暫停其他所有工作執行緒(Stop The World),直到收集結束。

暫停工作執行緒 是在用戶不可見的情況下進行

註:並發 與 並行的區別 a. 並發:在 某一時段內,交替執行多個任務(即先處理A再處理B,循環該過程) b. 並行:在 某一時刻內,同時執行多個任務(即同時處理A、B)

  • 單執行緒 只使用 一條執行緒 完成垃圾收集(GC執行緒)
  • 效率高 對於限定單CPU環境來說,Serial收集器沒有執行緒交互開銷(專一做垃圾收集),擁有更高的單執行緒收集效率。

垃圾收集高效,即其他工作執行緒停頓時間短(可控制在100ms內),只要垃圾收集發生的頻率不高,完全可以接受。

1.3 使用的垃圾收集演算法

複製 演算法

1.4 應用場景

客戶端模式下,虛擬機的 新生代區域

1.5 工作流程

2. Serial Old收集器

2.1 定義

Serial收集器 應用在老年代區域 的版本

2.2 優點

並發、單執行緒、效率高

Serial收集器,此處不作過多描述

2.3 使用的垃圾收集演算法

標記-整理 演算法

2.4 應用場景

  • 在客戶端模式下,虛擬機的老年代區域
  • 在伺服器模式下:
    1. Parallel Scavenge 收集器搭配使用
    2. 作為CMS收集器的後備預案,在並發收集發生Concurrent Mode Failure時使用

2.5 工作流程

3. ParNew 收集器

3.1 定義

Serial收集器 的 多執行緒 版本。

3.2 優點

  • 並發收集 在進行垃圾收集時,必須暫停其他所有工作執行緒(Stop The World),直到收集結束。

暫停工作執行緒 是在用戶不可見的情況下進行

  • 多執行緒收集 使用 多條垃圾收集執行緒(GC執行緒) 完成垃圾收集

由於存在執行緒交互的開銷,所以在單CPU環境下,性能差於 Serial收集器

  • CMS收集器配合工作 目前,只有ParNew 收集器能與 CMS收集器 配合工作
  1. 由於CMS收集器使用廣泛,所以該特點非常重要。
  2. 關於CMS收集器 下面會詳細說明

3.3 使用的垃圾收集演算法

複製 演算法

3.4 應用場景

伺服器模式下,虛擬機的 新生代區域

多執行緒收集

3.5 工作流程

4. Parallel Scavenge收集器

4.1 定義

ParNew 收集器的升級版

4.2 特點

  • 具備ParNew 收集器並發、多執行緒收集的特點
  • 以達到 可控制吞吐量 為目標 其他收集器的目標是: 儘可能縮短 垃圾收集時間,而Parallel Scavenge收集器的目標則是:達到 可控制吞吐量
  1. 吞吐量:CPU用於運行用戶程式碼的時間 與 CPU總消耗時間(運行用戶程式碼時間+垃圾收集時間)的比值
  2. 如:虛擬機總共運行100分鐘,其中垃圾收集時間=1分鐘、運行用戶程式碼時間 = 99分鐘,那吞吐量 = 99 / 100 = 99%
  • 自適應 該垃圾收集器能根據當前系統運行情況,動態調整自身參數,從而達到最大吞吐量的目標。
  1. 該特性稱為:GC 自適應的調節策略
  2. 這是Parallel Scavenge收集器與 ParNew 收集器 最大的區別

4.3 使用的垃圾收集演算法

複製 演算法

4.4 應用場景

伺服器模式下,虛擬機的 新生代區域

4.5 工作流程

5. Parallel Old收集器

5.1 定義

Parallel Scavenge收集器 應用在老年代區域 的版本

5.2 特點

以達到 可控制吞吐量 為目標、自適應調節、多執行緒收集

Parallel Scavenge收集器

5.3 使用的垃圾收集演算法

標記-整理 演算法

5.4 應用場景

伺服器模式下,虛擬機的 老年代區域

5.5 工作流程

6. CMS收集器

6.1 定義

Concurrent Mark Sweep,基於 標記-清除演算法的收集器

6.2 特點

6.2.1 優點

  • 並行 用戶執行緒 & 垃圾收集執行緒同時進行。

即在進行垃圾收集時,用戶還能工作。

  • 單執行緒收集 只使用 一條執行緒 完成垃圾收集(GC執行緒)
  • 垃圾收集停頓時間短 該收集器的目標是: 獲取最短回收停頓時間 ,即希望 系統停頓的時間 最短,提高響應速度

6.2.2 缺點

  • 總吞吐量會降低 因為該收集器對CPU資源非常敏感,在並發階段,雖不會導致用戶執行緒停頓,但會因為佔用部分執行緒(CPU資源)而導致應用程式變慢,總吞吐量會降低
  • 無法處理浮動垃圾 由於 並發清理時 用戶執行緒還在運行,所以會有新的垃圾不斷產生(即浮動垃圾),只能等到留待下一次GC時再清理掉。
  1. 因為這一部分垃圾出現在標記過程之後,所以CMS無法在當次GC中處理掉它們
  2. 因此,CMS無法等到老年代被填滿再進行Full GC,CMS需要預留一部分空間。即所謂的:可能出現Concurrent Mode Failure失敗而導致另一次Full GC產生。
  • 垃圾收集後會產生大量記憶體空間碎片 因為 CMS收集器是基於「標記-清除」演算法的。

6.3 使用的垃圾收集演算法

標記-清除 演算法

6.4 應用場景

重視應用的響應速度、希望系統停頓時間最短的場景

如互聯網移動端應用

6.5 工作流程

  • CMS 收集器 是基於 標記-清除演算法實現的收集器,工作流程較為複雜:(分為四個步驟)
    1. 初始標記
    2. 並發標記
    3. 重新標記
    4. 並發清除
  • 下面用一張圖詳細說明工作流程:
  • 由於整個過程中,耗時最長的並發標記 和 並發清除過程都可與用戶執行緒一起進行
  • 所以,CMS收集器的垃圾收集過程可看作是與用戶執行緒 並發執行的。

7. G1 收集器

7.1 定義

最新、技術最前沿的垃圾收集器

7.2 特點

  • 並行 用戶執行緒 & 垃圾收集執行緒同時進行。

即在進行垃圾收集時,用戶還能工作

  • 多執行緒 即使用 多條垃圾收集執行緒(GC執行緒) 進行垃圾收集

並發 & 並行 充分利用多CPU、多核環境下的硬體優勢 來縮短 垃圾收集的停頓時間

  • 垃圾回收效率高 G1 收集器是 針對性 對 Java堆記憶體區域進行垃圾收集,而非每次都對整個 Java 堆記憶體區域進行垃圾收集。
  1. G1收集器除了將 Java 堆記憶體區域分為新生代 & 老年代之外,還會細分為許多個大小相等的獨立區域( Region),然後G1收集器會跟蹤每個 Region里的垃圾價值大小,並在後台維護一個列表;每次回收時,會根據允許的垃圾收集時間 優先回收價值最大的Region,從而避免了對整個Java堆記憶體區域進行垃圾收集,從而提高效率。
  2. 因為上述機制,G1收集器還能建立可預測的停頓時間模型:即讓 使用者 明確指定一個長度為M毫秒的時間片段內,消耗在垃圾收集上的時間不得從超出N毫秒。即具備實時性
  • 分代收集 同時應用在 記憶體區域的新生代 & 老年代
  • 不會產生記憶體空間碎片
    1. 從整體上看,G1 收集器是基於 標記-整理演算法實現的收集器
    2. 從局部上看,是基於 複製演算法 實現 上述兩種演算法意味著 G1 收集器不會產生記憶體空間碎片。

7.3 使用的垃圾收集演算法

  • 對於新生代:複製演算法
  • 對於老年代:標記 – 整理演算法

7.4 應用場景

伺服器端虛擬機的記憶體區域(包括 新生代 & 老年代)

7.5 工作流程

  • G1 收集器的工作流程分為4個步驟:
    1. 初始標記
    2. 並發標記
    3. 最終標記
    4. 篩選回收
  • 下面用一張圖詳細說明工作流程

8. 總結

  • 本文對垃圾收集器的類型進行全面講解
  • 在接下來的日子,我會推出一系列講解JVM的文章,具體如下;