【JVM內存結構系列】四、不同垃圾回收器與堆內存的適配關系:從分代GC到Region GC

在JVM內存體系中,堆內存的“分代結構”與“對象流轉規則”是通用基礎,但垃圾回收器(GC)是決定堆內存實際表現的核心變量——不同GC為實現“低延遲”“高吞吐量”等目標,會對堆的劃分方式、對象管理邏輯、參數配置規則進行定制化改造。

本文作為JVM內存結構系列的第四篇,將以“堆內存”為紐帶,系統拆解經典分代GC、G1
GC、非分代GC
與堆的適配差異,幫你理解“堆的理論模型”如何在實際GC中落地,避免在調優時混淆“通用堆參數”與“GC專屬邏輯”,同時為后續實戰篇(GC問題排查)鋪墊核心認知。

一、核心認知:GC與堆的適配本質——“目標決定結構”

在分析具體GC前,需先明確一個核心邏輯:GC對堆的改造,本質是為了匹配自身的設計目標。不同GC的目標差異,直接導致了堆內存管理方式的分化:

  • 追求“高吞吐量”的GC(如Parallel Scavenge):會盡量簡化堆管理邏輯,減少GC線程與用戶線程的交互開銷;
  • 追求“低延遲”的GC(如CMS、ZGC):會通過復雜的堆劃分(如Region、Page)和并發回收機制,縮短用戶線程暫停(STW)時間;
  • 平衡“延遲與吞吐量”的GC(如G1):會采用動態化的堆管理策略,在兩者間找到最優解。

后續所有GC與堆的適配細節,都圍繞這個邏輯展開。

二、經典分代GC:嚴格遵循堆分代模型,適配中小堆內存

經典分代GC是JVM早期的主流選擇,其核心特點是完全遵循“年輕代+老年代”的物理分代模型,僅在“回收線程數”“老年代算法”上存在差異,適合堆內存≤4GB的場景(如單體應用、小型微服務)。

代表GC組合:SerialGC(Serial+Serial Old)、ParNew+CMS、Parallel Scavenge+Parallel Old。

2.1 與堆的適配共性:年輕代管理邏輯統一

所有經典分代GC的年輕代管理邏輯完全一致,均基于“復制算法”實現高效回收,具體適配細節如下:

  • 堆劃分規則:年輕代嚴格按“Eden:Survivor=8:1:1”劃分(可通過-XX:SurvivorRatio調整),老年代占堆總大小的2/3,物理上與年輕代連續;
  • 對象分配與晉升
    1. 新對象(非大對象)優先分配到Eden區,大對象(超過-XX:PretenureSizeThreshold)直接進入老年代;
    2. Minor GC時,Eden區存活對象復制到To Survivor,From Survivor存活對象按“年齡計數器”判斷:未達閾值(默認15,-XX:MaxTenuringThreshold)則復制到To Survivor,達標則晉升到老年代;
    3. 支持“動態年齡判斷”(-XX:TargetSurvivorRatio),Survivor區同年齡對象占比超閾值時,該年齡及以上對象提前晉升。
  • 回收線程特性:差異僅體現在“回收線程數”——SerialGC用單線程回收年輕代,ParNew和Parallel Scavenge用多線程回收(ParNew線程數與CPU核心數綁定,Parallel Scavenge可通過-XX:ParallelGCThreads調整)。

2.2 與堆的適配差異:老年代算法決定堆特性

經典分代GC的核心差異集中在老年代回收算法上,而算法選擇直接決定了老年代的“內存碎片情況”“大對象分配安全性”和“Full GC耗時”,最終影響堆的整體表現:

老年代GC組合核心算法堆內存特性(老年代)適配場景關鍵堆參數差異
Serial+Serial Old標記-整理(Mark-Compact)內存連續,無碎片;大對象分配安全;但Full GC單線程執行,耗時久(百毫秒~秒級)堆內存小(≤2GB)、低并發場景(如本地測試、輕量工具)無特殊參數,依賴-Xms/-Xmx控制堆大小
ParNew+CMSCMS:標記-清除(Mark-Sweep)
Serial Old:標記-整理(備用)
內存有碎片(標記-清除算法導致);大對象可能因無連續空間觸發Full GC;CMS并發回收,Full GC(CMS失敗時觸發)耗時久堆內存中等(2GB~4GB)、低延遲優先場景(如Web服務)-XX:CMSFullGCsBeforeCompaction:設置多少次CMS后執行整理(默認0,即每次CMS后整理,減少碎片)
Parallel Scavenge+Parallel OldParallel Old:標記-整理(Mark-Compact)內存連續,無碎片;大對象分配安全;多線程回收老年代,Full GC耗時比Serial Old短堆內存中等(2GB~4GB)、高吞吐量優先場景(如數據處理、批量任務)-XX:MaxGCPauseMillis:動態調整年輕代大小(縮小年輕代減少Minor GC耗時);-XX:GCTimeRatio:控制GC時間占比(默認99,即GC時間≤1%)

2.3 經典分代GC的堆適配局限

隨著堆內存增大(超過4GB),經典分代GC的局限逐漸凸顯:

  • 物理分代導致的回收范圍固定:Minor GC僅回收年輕代,Full GC回收全堆,堆越大Full GC耗時越長,無法靈活選擇回收區域;
  • 碎片問題(CMS):標記-清除算法導致老年代碎片累積,需頻繁執行整理操作(增加STW時間);
  • 參數依賴強:需手動調整年輕代比例、晉升閾值等參數,堆越大調優難度越高。

三、G1 GC:打破物理分代,堆內存的“Region化”改造

為解決經典分代GC在大堆內存(≥8GB)下的局限,G1 GC(Garbage-First GC)采用了Region化堆布局,通過“動態分代”和“優先回收垃圾多的區域”實現“低延遲+高吞吐量”的平衡,適合大型微服務、電商核心服務等場景。

3.1 堆布局革命:從“物理分代”到“Region動態角色”

G1 GC徹底打破了“年輕代與老年代物理連續”的傳統結構,將堆內存劃分為2048個大小相等的Region(每個Region大小1MB~32MB,通過-XX:G1HeapRegionSize設置,需為2的冪次方),每個Region動態扮演不同角色:

  • 年輕代Region:包括Eden Region和Survivor Region,邏輯上屬于年輕代,物理上分散在堆中;
  • 老年代Region:存放從年輕代晉升的對象,物理上與年輕代Region混雜;
  • 大對象Region(Humongous Region):專門存儲“大對象”(大小超過Region的50%),由連續多個Region組成,邏輯上屬于老年代。

這種布局的核心優勢:GC可靈活選擇部分Region回收(而非全堆),大幅縮短STW時間

3.2 與堆的適配細節:動態化的對象管理邏輯

G1 GC對堆的管理邏輯完全圍繞“Region”展開,與經典分代GC差異顯著:

3.2.1 年輕代管理:邏輯保留,物理動態
  • 年輕代Region的動態調整:G1沒有固定的年輕代大小(經典分代GC年輕代占堆1/3),而是根據“最大暫停時間目標”(-XX:MaxGCPauseMillis,默認200ms)動態調整年輕代Region數量——若Minor GC耗時超過目標,會減少年輕代Region;若年輕代過小導致晉升頻繁,會增加年輕代Region。
  • Minor GC流程:僅回收所有年輕代Region(Eden+Survivor),存活對象復制到新的Survivor Region或直接晉升到老年代Region,回收后清空原年輕代Region(無碎片)。
3.2.2 老年代管理:優先回收“垃圾多的Region”

G1的“Garbage-First”得名于其回收策略:每次GC優先選擇“垃圾占比高的Region”(老年代Region為主),具體邏輯:

  • Mixed GC(混合回收):當老年代Region占比超過“閾值”(-XX:InitiatingHeapOccupancyPercent,默認45%),觸發Mixed GC——同時回收所有年輕代Region和部分“垃圾占比高的老年代Region”,避免Full GC(G1盡量避免Full GC,Full GC時會退化為Serial Old算法,耗時極長)。
  • 老年代Region的晉升規則:無固定“年齡閾值”(經典分代GC默認15),G1通過“Region的存活對象占比”判斷——若Survivor Region的存活對象占比低,直接晉升為老年代Region;若占比高,則繼續作為Survivor Region保留。
3.2.3 大對象處理:Humongous Region的特殊邏輯
  • 分配規則:對象大小超過Region的50%時,直接分配到連續的Humongous Region,避免在普通Region中頻繁復制;
  • 回收時機:Humongous Region的回收與老年代Region同步(僅在Mixed GC或Full GC時回收),需注意:頻繁創建大對象會導致Humongous Region堆積,快速觸發Mixed GC,甚至Full GC(如頻繁創建100MB對象,Region大小設為32MB,則每個大對象占用4個Humongous Region)。

3.3 G1 GC的核心堆參數(與經典分代GC的差異)

G1 GC的參數設計更聚焦“目標控制”(如暫停時間),而非“分代比例”,核心堆相關參數如下:

參數名默認值核心作用(與堆適配相關)調優場景示例
-XX:G1HeapRegionSize自動計算(堆≤4GB時1MB,堆≤8GB時2MB,以此類推)設置單個Region大小,決定大對象閾值(Region大小的50%)若應用頻繁創建大對象(如50MB),可設為-XX:G1HeapRegionSize=32M(大對象閾值16MB,50MB對象需2個Region,減少Region數量)
-XX:MaxGCPauseMillis200ms控制GC最大暫停時間,G1會動態調整年輕代Region數量適配該目標低延遲場景(如支付服務)設為-XX:MaxGCPauseMillis=100,減少單次GC耗時
-XX:InitiatingHeapOccupancyPercent45%觸發Mixed GC的老年代Region占比閾值若堆內存大(如32GB),可提高至-XX:InitiatingHeapOccupancyPercent=60,減少Mixed GC頻率
-XX:G1MixedGCCountTarget8控制Mixed GC回收老年代Region的次數(默認8次內回收完符合條件的老年代Region)若老年代Region堆積快,可降低至-XX:G1MixedGCCountTarget=4,加快老年代回收

四、非分代GC:徹底拋棄分代模型,堆內存的“統一管理”

對于超大堆內存(≥64GB,如大數據、AI服務),“分代模型”已無法滿足“極致低延遲”(GC暫停≤10ms)的需求——非分代GC(ZGC、Shenandoah)徹底拋棄分代邏輯,采用“全堆統一管理+并發回收”,實現TB級堆內存的高效管理。

4.1 堆布局:無分代,僅按“內存單元”劃分

非分代GC的堆布局極度簡化,無“年輕代/老年代”概念,僅按固定大小的“內存單元”劃分:

  • ZGC(Z Garbage Collector):將堆分為Page(頁面),Page大小分三類:小頁面(2MB,存小對象)、中頁面(32MB,存中對象)、大頁面(≥2GB,存大對象),大頁面無需連續,直接映射物理內存;
  • Shenandoah GC:與G1類似,將堆分為Region(默認1MB),無動態分代角色,所有Region地位平等,大對象直接存放在連續Region中。

這種布局的核心優勢:GC可并發回收全堆(無需區分年輕代/老年代),STW時間僅與“對象引用遍歷”相關,與堆大小無關(ZGC堆從8GB擴容到1TB,STW時間仍保持在10ms內)。

4.2 與堆的適配細節:并發回收與無碎片管理

非分代GC的堆管理邏輯圍繞“并發”和“無碎片”設計,徹底解決了大堆內存下的延遲問題:

4.2.1 ZGC:基于“著色指針”的并發回收
  • 核心技術:著色指針:ZGC通過“指針編碼”(在64位指針中嵌入3位標記位)標記對象狀態(如“可回收”“正在遷移”),無需暫停用戶線程即可完成對象標記;
  • 堆內存特性
    1. 無碎片:采用“標記-復制”算法,回收時將存活對象復制到新Page,原Page清空后復用,堆內存始終連續;
    2. 大對象友好:大頁面(≥2GB)直接映射物理內存,無需復制(僅標記回收),支持TB級大對象;
    3. 無分代參數:無需配置“年輕代比例”“晉升閾值”,僅需通過-XX:ZHeapSize設置堆大小(初始=最大,避免擴容)。
4.2.2 Shenandoah GC:基于“讀屏障”的并發整理
  • 核心技術:讀屏障:Shenandoah在用戶線程讀取對象引用時插入“屏障”,記錄引用訪問,實現并發標記和并發整理;
  • 堆內存特性
    1. 無碎片:采用“標記-整理”算法(并發整理,無需復制對象),直接在原Region中移動對象,整理后內存連續;
    2. 回收效率高:全堆并發回收,STW時間僅用于“初始標記”和“最終標記”(各約1ms);
    3. 堆參數簡單:通過-XX:ShenandoahHeapRegionSize設置Region大小(默認1MB),-XX:ShenandoahGCHeuristics選擇回收策略(如“低延遲優先”“吞吐量優先”)。

4.3 非分代GC的堆適配優勢與局限

優勢局限
1. 堆大小無關性:STW時間不隨堆增大而增加,支持TB級堆;
2. 無碎片:無需擔心大對象分配失敗;
3. 參數簡單:無需手動調整分代參數,調優成本低;
4. 極致低延遲:GC暫停≤10ms,適合對延遲敏感的超大堆場景(如AI訓練、實時數據分析)。
1. 線程開銷高:著色指針(ZGC)和讀屏障(Shenandoah)會增加用戶線程開銷(約5%~10%);
2. JDK版本依賴:ZGC在JDK11正式發布,Shenandoah在JDK12正式發布,需升級JDK版本;
3. 工具支持:部分監控工具(如早期JVisualVM)對非分代GC的指標展示不完善。

五、實戰選型:根據堆內存特性匹配GC

掌握GC與堆的適配關系后,核心目標是“根據堆內存大小、應用目標(延遲/吞吐量)選擇合適的GC”,以下是實戰選型指南:

堆內存規模核心目標推薦GC堆適配關鍵注意事項
≤4GB低并發、簡單場景SerialGC無需復雜參數,堆大小設為-Xms2G -Xmx2G即可,避免頻繁擴容
4GB~8GB高吞吐量(如批量任務)Parallel Scavenge+Parallel Old依賴-XX:MaxGCPauseMillis動態調整年輕代,避免手動設置-XX:MaxNewSize
4GB~8GB低延遲(如Web服務)ParNew+CMS需配置-XX:CMSFullGCsBeforeCompaction=3(3次CMS后整理碎片),避免大對象堆積
8GB~64GB低延遲+高吞吐量(如電商核心服務)G1 GC1. 設-XX:G1HeapRegionSize=16M(堆32GB時);
2. 控制-XX:MaxGCPauseMillis=100
3. 避免頻繁創建超過Region 50%的大對象
≥64GB極致低延遲(如AI訓練、實時數據)ZGC/Shenandoah1. ZGC設-XX:ZHeapSize=64G(初始=最大);
2. Shenandoah設-XX:ShenandoahGCHeuristics=latency(低延遲優先);
3. 確保JDK版本≥11(ZGC)/12(Shenandoah)

六、小結與預告:GC與堆的聯動是調優核心

本文通過“經典分代GC→G1 GC→非分代GC”的遞進邏輯,解析了GC與堆內存的適配本質:

  1. 經典分代GC是“堆分代模型的嚴格實現”,適合中小堆,核心差異在老年代算法;
  2. G1 GC是“堆Region化的過渡方案”,通過動態分代平衡延遲與吞吐量,適合大堆;
  3. 非分代GC是“堆統一管理的終極形態”,通過并發回收實現極致低延遲,適合超大堆。

理解這種適配關系,是后續GC調優和內存問題排查的關鍵——比如“G1的Humongous Region堆積導致OOM”“CMS的老年代碎片導致Full GC頻繁”等問題,本質都是“GC特性與堆內存使用不匹配”。

下一篇(系列第五篇),我們將聚焦《JVM方法區與元空間:從永久代到元空間的變遷》,解析堆外的“類信息存儲區域”,以及它與堆內存、GC的關聯邏輯,進一步完善JVM內存結構的認知框架。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94173.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94173.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94173.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Zemax光學設計輸出3D

輸出立體數據文件(IGES/STEP/SAT/STL 格式)的參數設置界面,各參數含義如下:1. 起始面/終止面:設定要輸出立體數據對應的光學表面范圍,從第 0 個表面到第 9 個表面 ,限定參與輸出的光學結構表面區…

模塊測試與低功耗模式全攻略

一、模塊測試流程在測試一個模塊時,建議遵循以下步驟:基本測試:測試該模塊的寄存器讀寫功能是否正常。可以向每個寄存器寫入 0x5A5A 和 0xA5A5,這兩種模式可以覆蓋對寄存器寫入 0 和 1 的情況。進階測試:在基本測試通過…

機器學習實驗三、使用決策樹算法預測泰坦尼克號幸存者

實驗目的1. 掌握特征工程,會進行特征提取與特征選擇,會進行缺失值填充。2. 建立決策樹模型,解決實際問題。3. 會對模型進行調試,能夠繪制并保存決策樹。實驗環境Python 3.7.0,Sklearn ,PyCharm實驗原理1、特…

從全棧開發到微服務架構:一次真實的Java面試實錄

從全棧開發到微服務架構:一次真實的Java面試實錄 面試官與應聘者介紹 面試官:李明,某互聯網大廠技術負責人,擅長Java后端、微服務及云原生架構。 應聘者:張偉,28歲,碩士學歷,擁有5年…

新的 Gmail 網絡釣魚攻擊利用 AI 提示注入來逃避檢測

網絡釣魚一直以來都是為了欺騙人們。但在這次活動中,攻擊者不僅瞄準用戶,還試圖操縱基于人工智能的防御系統。 這是我上周記錄的Gmail 網絡釣魚鏈的演變。那次攻擊活動依賴于緊迫性和重定向,但這次引入了隱藏的 AI 提示,旨在混淆…

Restful風格設計

文章目錄什么是Restful風格?RESTful API設計最佳實踐1. URL設計原則2. HTTP狀態碼的正確使用3. 統一的響應格式實際案例:用戶管理系統API總結什么是Restful風格? 我的理解是:Restful是一種基于HTTP協議的架構設計風格&#xff0c…

深入 Glide 圖像變換:自定義效果、GIF處理與組合變換

在 Android 開發中,Glide 的強大不僅在于其高效的加載和緩存能力,更在于其無與倫比的可擴展性,尤其是在圖像處理層面。當內置的 fitCenter() 和 circleCrop() 無法滿足你的設計需求時,自定義 Transformation 便是你的終極武器。本…

數據挖掘 4.8 評估泛化能力

4.8 Estimating Generalization 4.8 評估泛化能力 評估模型的泛化能力如何合理評估模型的泛化能力指導原則 (Guidelines)存在的問題 (Issues)K-fold 交叉驗證(Cross-Validation)留一交叉驗證(Leave One Out CV)(LOOCV)Stratification 分層訓練…

46.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--擴展功能--集成網關--網關集成日志

本篇文章,我們一起在網關中集成日志功能,我們要在網關中記錄下游微服務出現的異常信息、請求信息以及響應信息。在微服務架構中,網關作為系統的入口,承擔著非常重要的職責。通過在網關層面集成日志功能,我們可以更好地…

使用 FastAPI 的 WebSockets 和 Elasticsearch 來構建實時應用

作者:來自 Elastic Jeffrey Rengifo 學習如何使用 FastAPI WebSockets 和 Elasticsearch 構建實時應用程序。 更多閱讀:使用 FastAPI 構建 Elasticsearch API 想要獲得 Elastic 認證嗎?看看下一次 Elasticsearch Engineer 培訓什么時候開始&…

華為云ModelArts+Dify AI:雙劍合璧使能AI應用敏捷開發

引言:AI應用開發的敏捷化轉型需求 隨著大語言模型(LLM)技術的迅猛發展,企業與開發者對AI應用開發的敏捷化轉型需求日益凸顯,亟需將大模型能力快速轉化為實際業務價值。傳統AI開發模式中,復雜的模型工程化、流程編排和部署維護工作往往需要專業技術團隊支撐,典型痛點包括…

網絡實踐——Socket編程UDP

文章目錄Socket編程UDPUDP接口的使用鋪墊socketrecvform && sendtobind字節序轉化使用(Tips)實踐部分version_1echo_serverversion_2dict_serverversion_3chat_serverSocket編程UDP 在了解了相關的網絡基礎知識后,我們不會像學系統知識一樣,先學…

GD32 波形發生器,三角波,正弦波,方波。AD9833+MCP410生成和MCU自身的DAC生成。波形,頻率,振幅可以通過按鍵和OLED調整輸出。

DIY一個簡易的信號發生器驅動板,主要是三角波和正弦波,方波。主板有兩個通道能輸出波形,CH0由AD9833MCP410AD8051放大電路組成,理論可以生成0.1-12.5MHZ的頻率信號,單電源振幅范圍是1-9V。CH1由MCU外設DAC生成的信號&a…

VS2022的MFC中關聯使用控制臺并用printf輸出調試信息

前言 MFC一般在調試的時候,可以在IDE中方便的看到調試的信息。但是,有時候運行的時候也要看調試的信息怎么辦?最好如同在Console(控制臺)程序中輸出一般的方便,可以么?可以的。 一、設置 1.1、加…

ZKmall模塊商城的推薦數據體系:從多維度采集到高效存儲的實踐

在電商領域,個性化推薦已成為提升用戶體驗與轉化效率的核心手段。ZKmall 模塊商城基于用戶行為、商品屬性與交易數據,構建了一套完整的推薦算法體系,而數據采集的全面性與存儲的高效性是該體系的基礎。本文將聚焦推薦算法的 “數據輸入端”&a…

Qt + windows+exe+msvc打包教程

目錄 1. Qt + windows+exe+msvc打包教程1 1.1. Enigma Virtual Box下載?1 1.2. Enigma Virtual Box安裝2 1.3. Qt 打包成獨立exe教程6 1.3.1. Qt項目創建6 1.3.2. Qt項目編譯13 1.3.3. Qt 項目打包 windeployqt命令14 1.3.4. Qt 項目打包 Enigma Virtual Box工具18 Q…

大語言模型應用開發——利用OpenAI函數與LangChain結合從文本構建知識圖譜搭建RAG應用全流程

概述 從文本等非結構化數據中提取結構化信息并非新鮮事物,但大語言模型(LLMs)為該領域帶來了重大變革。以往需要機器學習專家團隊策劃數據集并訓練自定義模型,如今只需訪問LLM即可實現,顯著降低了技術門檻&#xff0c…

Vue3+Spring Boot技術棧,前端提交混合表單數據(普通字段+文件字段),上傳文件,后端插入數據,將文件保存到數據庫

一、技術棧1、前端 Vue3 Element Plus TypeSprict2、后端 Spring Boot 3.2.12 Mybatis Plus3、模型特點3.1、表格展示列表數據3.2、行點擊,彈出對話框3.3、前端使用 FormData 提交混合表單數據,包含普通字段和文件字段3.4、文件對應數據庫結構類型為 …

【Qt開發】Qt的背景介紹(四)

目錄 1 -> Qt Hello World 程序 1.1 -> 使用“按鈕”實現 1.1.1 -> 純代碼方式實現 1.1.2 -> 可視化操作實現 1.2 -> 使用“標簽”實現 1.2.1 -> 純代碼方式實現 1.2.2 -> 可視化操作實現 2 -> 項目文件解析 2.1 -> .pro文件解析 2.2 -&g…

Linux驅動開發筆記(六)——pinctrl GPIO

開發板:imx6ull mini 虛擬機:VMware17 ubuntu:ubuntu20.04 視頻:第8.1講 pinctrl和gpio子系統試驗-pincrl子系統詳解_嗶哩嗶哩_bilibili 文檔:《【正點原子】I.MX6U嵌入式Linux驅動開發指南.pdf》四十五章 這一章…