前言
- 垃圾收集器 是 垃圾收集算法 的具體實現
- 本文將對市面上常見的垃圾收集器類型進行講解,希望你們會喜歡
在接下來的日子,我會推出一系列講解
JVM
的文章,具體如下;感興趣可持續關注Carson_Ho的安卓開發筆記
垃圾收集器類型
- 垃圾收集器 是 垃圾收集算法 的具體實現
- 現在主流的垃圾收集器有 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 應用場景
- 在客戶端模式下,虛擬機的老年代區域
- 在服務器模式下:
- 與
Parallel Scavenge
收集器搭配使用 - 作爲
CMS
收集器的後備預案,在併發收集發生Concurrent Mode Failure
時使用
- 與
2.5 工作流程
3. ParNew 收集器
3.1 定義
Serial
收集器 的 多線程 版本。
3.2 優點
- 併發收集
在進行垃圾收集時,必須暫停其他所有工作線程(Stop The World
),直到收集結束。
暫停工作線程 是在用戶不可見的情況下進行
- 多線程收集
使用 多條垃圾收集線程(GC
線程) 完成垃圾收集
由於存在線程交互的開銷,所以在單
CPU
環境下,性能差於Serial
收集器
- 與
CMS
收集器配合工作
目前,只有ParNew
收集器能與CMS
收集器 配合工作
- 由於
CMS
收集器使用廣泛,所以該特點非常重要。- 關於
CMS
收集器 下面會詳細說明
3.3 使用的垃圾收集算法
複製 算法
3.4 應用場景
服務器模式下,虛擬機的 新生代區域
多線程收集
3.5 工作流程
4. Parallel Scavenge收集器
4.1 定義
ParNew
收集器的升級版
4.2 特點
-
具備ParNew 收集器併發、多線程收集的特點
-
以達到 可控制吞吐量 爲目標
其他收集器的目標是: 儘可能縮短 垃圾收集時間,而Parallel Scavenge
收集器的目標則是:達到 可控制吞吐量
- 吞吐量:
CPU
用於運行用戶代碼的時間 與CPU
總消耗時間(運行用戶代碼時間+垃圾收集時間)的比值- 如:虛擬機總共運行100分鐘,其中垃圾收集時間=1分鐘、運行用戶代碼時間 = 99分鐘,那吞吐量 = 99 / 100 = 99%
- 自適應
該垃圾收集器能根據當前系統運行情況,動態調整自身參數,從而達到最大吞吐量的目標。
- 該特性稱爲:
GC
自適應的調節策略- 這是
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時再清理掉。
- 因爲這一部分垃圾出現在標記過程之後,所以
CMS
無法在當次GC
中處理掉它們- 因此,
CMS
無法等到老年代被填滿再進行Full GC,CMS需要預留一部分空間。即所謂的:可能出現Concurrent Mode Failure
失敗而導致另一次Full GC
產生。
- 垃圾收集後會產生大量內存空間碎片
因爲CMS
收集器是基於“標記-清除”算法的。
6.3 使用的垃圾收集算法
標記-清除 算法
6.4 應用場景
重視應用的響應速度、希望系統停頓時間最短的場景
如互聯網移動端應用
6.5 工作流程
-
CMS
收集器 是基於 標記-清除算法實現的收集器,工作流程較爲複雜:(分爲四個步驟)- 初始標記
- 併發標記
- 重新標記
- 併發清除
- 下面用一張圖詳細說明工作流程:
- 由於整個過程中,耗時最長的併發標記 和 併發清除過程都可與用戶線程一起進行
- 所以,
CMS
收集器的垃圾收集過程可看作是與用戶線程 併發執行的。
7. G1 收集器
7.1 定義
最新、技術最前沿的垃圾收集器
7.2 特點
- 並行
用戶線程 & 垃圾收集線程同時進行。
即在進行垃圾收集時,用戶還能工作
- 多線程
即使用 多條垃圾收集線程(GC
線程) 進行垃圾收集
併發 & 並行 充分利用多CPU
、多核環境下的硬件優勢 來縮短 垃圾收集的停頓時間
- 垃圾回收效率高
G1
收集器是 針對性 對Java
堆內存區域進行垃圾收集,而非每次都對整個Java
堆內存區域進行垃圾收集。
- 即
G1
收集器除了將Java
堆內存區域分爲新生代 & 老年代之外,還會細分爲許多個大小相等的獨立區域(Region
),然後G1收集器會跟蹤每個Region
裏的垃圾價值大小,並在後臺維護一個列表;每次回收時,會根據允許的垃圾收集時間 優先回收價值最大的Region
,從而避免了對整個Java堆內存區域進行垃圾收集,從而提高效率。- 因爲上述機制,
G1
收集器還能建立可預測的停頓時間模型:即讓 使用者 明確指定一個長度爲M毫秒的時間片段內,消耗在垃圾收集上的時間不得從超出N毫秒。即具備實時性
-
分代收集
同時應用在 內存區域的新生代 & 老年代 -
不會產生內存空間碎片
- 從整體上看,
G1
收集器是基於 標記-整理算法實現的收集器 - 從局部上看,是基於 複製算法 實現
上述兩種算法意味着G1
收集器不會產生內存空間碎片。
- 從整體上看,
7.3 使用的垃圾收集算法
- 對於新生代:複製算法
- 對於老年代:標記 - 整理算法
7.4 應用場景
服務器端虛擬機的內存區域(包括 新生代 & 老年代)
7.5 工作流程
G1
收集器的工作流程分爲4個步驟:- 初始標記
- 併發標記
- 最終標記
- 篩選回收
- 下面用一張圖詳細說明工作流程
8. 總結
- 本文對垃圾收集器的類型進行全面講解
- 在接下來的日子,我會推出一系列講解
JVM
的文章,具體如下;感興趣的同學可以繼續關注本人運營的CSDN博客