G1 垃圾收集器深入剖析(圖文超詳解)
G1(Garbage First)垃圾收集器,是目前垃圾回收技術最前沿的成果之一。
G1 同 CMS 垃圾回收器一樣,關注最小時延的垃圾回收器,適合大尺寸堆記憶體的垃圾收集。 G1 最大的特點是引入分割槽的思路,弱化了分代的概念 ,合理利用垃圾收集各個週期的資源,解決了其他收集及 CMS 的很多缺陷。
官方推薦使用 G1 來代替 CMS。
我們本篇重點了解 G1 收集器的基本概念、堆記憶體、回收流程、GC模式、推薦用例等。
目錄
- G1 收集器概述
- G1 的堆記憶體演算法
- 1. G1 之前的 JVM 記憶體模型
- 2. G1收集器的記憶體模型
- G1回收流程
- 1. G1 收集器的階段(步驟)
- G1 的 GC 模式
- 1. YoungGC 年輕代收集
- 2. mixed gc
-
G1 的推薦用例
G1 收集器概述
HotSpot 團隊一直努力朝著高效收集、減少停頓 (STW: Stop The World) 的方向努力,貢獻了從序列 Serial 收集器、到並行收集器 Parallerl 收集器,再到 CMS 併發收集器,乃至如今的 G1 在內的一系列優秀的垃圾收集器。
G1(Garbage First) 垃圾收集器,是 關注最小時延的垃圾回收器,也 同樣適合大尺寸堆記憶體的垃圾收集,官方推薦選擇使用 G1 來替代 CMS 。
1. G1 收集器的最大特點
- G1最大的特點是引入分割槽的思路,弱化了分代的概念。
- 合理利用垃圾收集各個週期的資源,解決了其他收集器、甚至 CMS 的眾多缺陷。
2. G1 的改進(相比較 CMS )
- 演算法: G1 基於標記--整理演算法, 不會產生空間碎片,在分配大物件時,不會因無法得到連續的空間,而提前觸發一次 FULL GC 。
- 停頓時間可控: G1可以透過設定預期停頓時間(Pause Time)來控制垃圾收集時間避免應用雪崩現象。
- 並行與併發:G1 能更充分的利用 CPU 多核環境下的硬體優勢,來縮短 stop the world 的停頓時間。
3. CMS 和 G1 的區別
- CMS 中, 堆被分為 PermGen,YoungGen,OldGen ;而 YoungGen 又分了兩個 survivo 區域。在 G1 中,堆被平均分成幾個區域 (region) ,在每個區域中,雖然也保留了新老代的概念,但是收集器是以整個區域為單位收集的。
- G1 在回收記憶體後,會立即同時做合併空閒記憶體的工作;而 CMS ,則預設是在 STW(stop the world)的時候做。
- G1 會在 Young GC 中使用;而 CMS 只能在 O 區使用。
4. G1 收集器的應用場景
目前,CMS 還是預設首選的 GC 策略。
G1 垃圾收集演算法,主要應用在多 CPU 大記憶體的服務中,在滿足高吞吐量的同時,儘可能的滿足垃圾回收時的暫停時間。
在以下場景中,G1 更適合:
- 服務端多核 CPU、JVM 記憶體佔用較大的應用(至少大於4G);
- 應用在執行過程中,會產生大量記憶體碎片、需要經常壓縮空間;
-
想要更可控、可預期的 GC 停頓週期,防止高併發下應用雪崩現象。
G1 的堆記憶體演算法
1. G1 之前的 JVM 記憶體模型
- 新生代:伊甸園區 (eden space) + 2個倖存區
- 老年代
- 持久代 (perm space):JDK1.8 之前
- 元空間 (metaspace):JDK1.8 之後取代持久代
2. G1收集器的記憶體模型
2.1 G1 堆記憶體結構
堆記憶體會被切分成為很多個固定大小區域(Region),每個是連續範圍的虛擬記憶體。
堆記憶體中一個區域 (Region) 的大小,可以透過 -XX:G1HeapRegionSize 引數指定,大小區間最小 1M 、最大 32M ,總之是 2 的冪次方。
預設是將堆記憶體按照 2048 份均分。
2.2 G1 堆記憶體分配
每個 Region 被標記了 E、S、O 和 H,這些區域在邏輯上被對映為 Eden,Survivor 和老年代。
存活的物件從一個區域轉移(即複製或移動)到另一個區域。區域被設計為並行收集垃圾,可能會暫停所有應用執行緒。如上圖所示,區域可以分配到 Eden,survivor 和老年代。
此外,還有第四種型別,被稱為巨型區域(Humongous Region)。
Humongous 區域主要是為儲存超過 50% 標準 region 大小的物件設計,它用來專門存放巨型物件。如果一個 H 區裝不下一個巨型物件,那麼 G1 會尋找連續的 H 分割槽來儲存。為了能找到連續的 H 區,有時候不得不啟動 Full GC 。
G1 回收流程
在執行垃圾收集時,G1 以類似於 CMS 收集器的方式執行。
1. G1 收集器的階段,大致分為以下步驟:
1.1 G1 執行的第一階段:初始標記 ( Initial Marking )
這個階段是 STW(Stop the World ) 的,所有應用執行緒會被暫停,標記出從 GC Root 開始直接可達的物件。
1.2 G1 執行的第二階段:併發標記
從 GC Roots 開始,對堆中物件進行可達性分析,找出存活物件,耗時較長。
當併發標記完成後,開始最終標記 ( Final Marking ) 階段。
1.3 最終標記
標記那些在併發標記階段發生變化的物件,將被回收。
1.4 篩選回收
首先,對各個 Regin 的回收價值和成本進行排序,根據使用者所期待的 GC 停頓時間,來指定回收計劃,回收一部分 Region 。
G1 中提供了 Young GC、 Mixed GC 兩種垃圾回收模式,這兩種垃圾回收模式,都是 Stop The World(STW) 的。
G1 的 GC 模式
1. YoungGC 年輕代收集
在分配一般物件(非巨型物件)時,當所有 eden region 使用達到最大閥值、並且無法申請足夠記憶體時,會觸發一次 YoungGC 。
每次 younggc 會回收所有Eden 、以及 Survivor 區,並且將存活物件複製到 Old 區以及另一部分的 Survivor 區。
YoungGC 的回收過程:
- 根掃描,跟 CMS 類似,Stop the world,掃描 GC Roots 物件;
- 處理 Dirty card,更新 RSet;
- 掃描 RSet ,掃描 RSet 中所有 old 區,對掃描到的 young 區或者 survivor 區的引用;
- 複製掃描出的存活的物件到 survivor2/old 區;
- 處理引用佇列、軟引用、弱引用、虛引用。
2. mixed gc
當越來越多的物件晉升到老年代 old region 時,為了避免堆記憶體被耗盡,虛擬機器會觸發一個混合的垃圾收集器,即 mixed gc ,該演算法並不是一個 old gc ,除了回收整個 young region ,還會回收一部分的 old region 。
這裡需要注意:是一部分老年代,而不是全部老年代,可以選擇哪些 old region 進行收集,從而可以對垃圾回收的耗時時間進行控制。
G1 沒有 fullGC 概念,需要 fullGC 時,呼叫 serialOldGC 進行全堆掃描(包括 eden、survivor、o、perm)。
G1 的推薦用例
G1 的第一個重要特點:是為使用者的應用程式的提供一個低GC延時和大記憶體GC的解決方案。
這意味著堆大小 6GB 或更大,穩定和可預測的暫停時間將低於 0.5 秒。
如果應用程式使用 CMS 或 ParallelOld 垃圾回收器,具有一個或多個以下特徵,將有利於切換到 G1:
- Full GC 持續時間太長或太頻繁;
- 物件分配率或年輕代升級老年代很頻繁;
- 不期望的很長的垃圾收集時間或壓縮暫停(超過 0.5 至 1 秒)。
注意:
如果你正在使用 CMS 或 ParallelOld 收集器,且應用程式沒有遇到長時間的垃圾收集暫停,則保持當前收集器就可以了。升級 JDK ,並不需要更新收集器為 G1 。
以上,是 G1 垃圾收集器的解析,歡迎評論區留言交流或擴充。
如果覺得有用, 請順手 關注+ 點贊+ 轉發 支援下,謝謝。
作者簡介
陳睿 | mikechen , 10 年 + 大廠架構經驗,「mikechen 的網際網路架構」系列文章作者,專注於網際網路架構技術。
閱讀 「mikechen 的網際網路架構」40W 字技術文章合集
Java 併發 | JVM | MySQL | Spring | Redis | 分散式 | 高併發
以上合集,關注「mikechen 的網際網路架構」公眾號,回覆 : 架構 ,即可獲得。
--- end ---
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011997/viewspace-2921536/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java G1 垃圾收集器Java
- 瞭解JDK的新型超快垃圾收集器:Shenandoah、ZGC和改進的G1 - oracleJDKNaNGCOracle
- 【淺度渣文】JVM——G1收集器JVM
- 難頂!面試官問我G1垃圾收集器面試
- 深入理解 JVM 之 垃圾收集器JVM
- Java虛擬機器詳解(四)------垃圾收集器Java虛擬機
- 關於生產環境改用G1垃圾收集器的思考
- 深入理解JVM,7種垃圾收集器JVM
- CMS、G1收集器
- ☕[JVM技術指南](4)垃圾回收子系統(Garbage Collection System)之G1垃圾收集器SATBJVM
- 垃圾收集器
- 深入理解JVM(三)——垃圾收集策略詳解JVM
- 深入理解java虛擬機器之垃圾收集器Java虛擬機
- 探索G1垃圾回收器
- 一張圖提示如何選擇Java垃圾收集器?Java
- 垃圾收集器學習
- JVM垃圾收集器(八)JVM
- 超詳細圖文介紹,華為桌面雲解決方案
- 【JVM專題】JVM從概述到調優圖文詳解,含思維腦圖深度剖析!JVM
- 深入理解JVM記憶體回收機制(不包含垃圾收集器)JVM記憶體
- JVM垃圾收集器總結JVM
- JVM垃圾收集器專題JVM
- JVM 經典垃圾收集器JVM
- 垃圾收集器與記憶體分配策略_hotspot垃圾收集演算法實現和垃圾收集器記憶體HotSpot演算法
- 十、jvm垃圾回收演算法、垃圾收集器、引用你真的瞭解麼?JVM演算法
- java幾種垃圾收集方法和垃圾收集器Java
- Java泛型詳解,史上最全圖文詳解!Java泛型
- 垃圾回收之G1收集過程
- PopClip使用教程圖文詳解
- 深入理解JVM虛擬機器3:垃圾回收器詳解JVM虛擬機
- 《深入理解java虛擬機器》筆記3——7種垃圾收集器Java虛擬機筆記
- 深入剖析Redis系列(三) - Redis叢集模式搭建與原理詳解Redis模式
- 【恩墨學院】深入剖析 - Oracle SCN機制詳細解讀Oracle
- GC 分代回收 - 垃圾收集器GC
- 13.G1垃圾收集器
- JVM(五)-垃圾收集器入門JVM
- G1 垃圾回收器簡單調優
- 垃圾回收之CMS、G1、ZGC對比GC