JVM(11)——詳解CMS垃圾回收器

CMS (Concurrent Mark-Sweep) 垃圾回收器。它是 JDK 1.4 后期引入,并在 JDK 5 - JDK 8 期間廣泛使用的一種以低停頓時間 (Low Pause Time)?為主要目標的老年代垃圾回收器。它是 G1 出現之前解決 Full GC 長停頓問題的主要方案。

一、CMS 的設計目標與定位

  1. 核心目標:最小化應用停頓時間 (STW - Stop-The-World)。

    • 特別關注老年代垃圾回收引起的停頓。

    • 旨在避免傳統 Serial Old GC(標記-整理)導致的長時間、全局性的停頓,這對交互式應用(如 Web 服務器、GUI 應用)至關重要。

  2. 實現方式:并發 (Concurrent) 收集。

    • 將垃圾回收中最耗時的標記 (Marking)?和清除 (Sweeping)?階段,盡可能與應用線程并發執行,從而大大減少需要 STW 的時間。

  3. 算法:標記-清除 (Mark-Sweep)。

    • 標記:?找出所有存活的對象。

    • 清除:?回收未被標記(即死亡)的對象占用的空間。

    • 注意:?它不進行壓縮 (Compaction),這是它產生內存碎片的主要原因。

  4. 分代收集:?CMS 主要管理老年代 (Old Generation)。它通常與一個年輕代收集器搭配使用,如?ParNew(并行復制算法,Serial 的多線程版本)或?Serial

  5. 定位:?在 G1 成熟之前,CMS 是追求低延遲老年代回收的首選方案,尤其適用于中小型堆(如 4GB - 8GB)、CPU 資源相對充足且能容忍一些內存碎片和額外 CPU 開銷的應用。

二、CMS 的工作階段 (Phases)

CMS 的垃圾回收周期(針對老年代)由多個階段組成,其中只有部分階段需要 STW:

  1. 初始標記 (Initial Mark - STW)

    • 目標:?標記從?GC Roots?直接可達?的老年代對象(速度很快)。

    • STW 原因:?需要暫停應用線程以確保在一致性的快照下快速掃描 GC Roots(線程棧、靜態變量、JNI 引用等)。

    • 優化:?這個階段通常借道一次?Young GC(Minor GC)來完成。因為 Young GC 本身就需要 STW 并掃描 GC Roots,CMS 可以“搭便車”標記那些從根集直接引用的老年代對象,避免了額外的完整根掃描停頓。所以 CMS 觸發的時機往往緊跟在一次 Young GC 之后。

  2. 并發標記 (Concurrent Mark - Concurrent)

    • 目標:?從“初始標記”階段標記的直接可達對象開始,遍歷整個老年代對象圖,標記所有間接可達的存活對象。

    • 并發性:?這是 CMS 減少停頓的關鍵!這個階段與應用線程同時運行。應用線程可以繼續創建新對象、更新引用關系。

    • 挑戰 - 浮動垃圾 (Floating Garbage):?因為在標記過程中應用線程還在運行,可能會產生新的垃圾對象(標記階段結束后才成為垃圾)或者使已標記的對象變成垃圾。同時,應用線程修改對象引用關系可能導致“漏標”或“多標”問題。CMS 使用?增量更新 (Incremental Update)?算法來解決對象引用變化的問題(與 G1 的 SATB 不同)。

    • 挑戰 - 耗時:?遍歷整個老年代對象圖,即使并發,也可能花費較長時間,特別是大堆。

  3. 重新標記 (Remark - STW)

    • 目標:?修正“并發標記”階段因應用線程繼續運行而導致的標記變動,確保所有在并發標記期間存活的對象都被正確標記。處理在并發階段新晉升到老年代的對象(如果搭配 ParNew,晉升發生在 Young GC 的 STW 階段,相對容易處理)。

    • STW 原因:?為了獲得一個最終準確的存活對象視圖,需要在一個確定的點上暫停所有應用線程。

    • 優化:?這個階段通常比“初始標記”長,但比“并發標記”短得多。JVM 會使用多線程并行處理來加速。可以啟用?-XX:+CMSScavengeBeforeRemark?參數,在重新標記前強制觸發一次 Young GC,清理掉年輕代的垃圾,減少需要掃描的年輕代對象數量(年輕代對象也可能引用老年代對象),從而縮短 STW 時間。

  4. 并發清除 (Concurrent Sweep - Concurrent)

    • 目標:?回收那些在標記階段被確定為死亡對象所占用的內存空間。

    • 并發性:?這個階段也與應用線程同時運行。應用線程可以繼續分配新對象(在空閑列表管理的內存區域)。

    • 算法:?使用空閑列表 (Free List)?管理回收后的空間。清除器遍歷內存,將連續的死對象空間合并成空閑塊,記錄在空閑列表中,供后續分配使用。

    • 結果:?回收了垃圾內存,但不進行內存整理壓縮。這導致了內存碎片問題。

  5. 并發重置 (Concurrent Reset - Concurrent)

    • 目標:?為下一次 CMS 周期重置內部數據結構(如標記位圖)。

    • 并發性:?與應用線程同時運行,無停頓。

三、CMS 的核心特性與優勢

  1. 低停頓時間 (Low Pause Time):?這是 CMS 最大的優勢。通過將最耗時的標記和清除工作并發執行,顯著減少了 STW 的時間(主要集中在初始標記和重新標記階段),使得老年代回收對應用響應時間的影響大大降低。

  2. 并發收集 (Concurrent Collection):?真正實現了垃圾回收線程與應用線程在大部分時間并行工作。

  3. 適用于延遲敏感型應用:?在 G1 成熟之前,是 Web 服務器、交易系統等需要快速響應的應用的首選老年代回收器。

四、CMS 的缺點與挑戰

  1. 內存碎片 (Memory Fragmentation):

    • 根本原因:?使用標記-清除算法且不壓縮內存。長時間運行后,老年代會由許多存活對象和大小不一、分散的空閑內存塊組成。

    • 后果:

      • 分配失敗:?即使老年代總的空閑空間足夠,也可能因為找不到足夠大的連續空間來分配一個大對象(或晉升對象),從而觸發?Full GC (Serial Old GC)

      • Full GC 時間長:?Serial Old GC 是單線程的標記-整理-壓縮算法,在大堆上進行壓縮會導致非常長的 STW 停頓,違背了使用 CMS 的初衷。

    • 緩解措施:

      • -XX:+UseCMSCompactAtFullCollection?(默認 true): 在不得不進行 Full GC 時,在 Full GC 后進行內存壓縮。

      • -XX:CMSFullGCsBeforeCompaction=n?(默認 0): 設定在多少次不壓縮的 Full GC 后,執行一次帶壓縮的 Full GC。0?表示每次 Full GC 都壓縮(推薦)。但這仍然意味著要經歷一次長時間的 Full GC。

  2. 并發模式失敗 (Concurrent Mode Failure):

    • 觸發條件:

      • 老年代空間不足:?在 CMS 并發周期(標記和清除)完成之前,老年代空間就被填滿了。這通常發生在:

        • 老年代分配/晉升速率過快,超過 CMS 回收速度。

        • 浮動垃圾過多,占用了本應回收的空間。

        • 并發周期啟動太晚(-XX:CMSInitiatingOccupancyFraction?設置過高)。

      • 晉升失敗 (Promotion Failed):?Young GC 后,存活對象需要晉升到老年代,但老年代沒有足夠的連續空間容納它們(即使總空間可能夠,但碎片導致)。

    • 后果:?JVM 會立即中斷?CMS 并發周期,并觸發一次?Full GC (Serial Old GC)。這會導致一個計劃外的、長時間的 STW 停頓。

    • 預防措施:

      • 合理設置?-XX:CMSInitiatingOccupancyFraction降低老年代空間占用閾值(如從默認 68% 設到 50% 或更低),盡早啟動 CMS 并發周期,給并發回收留出足夠的時間窗口和空間裕度。

      • 必須配合?-XX:+UseCMSInitiatingOccupancyOnly?使用:確保 JVM?根據?CMSInitiatingOccupancyFraction?的值啟動 CMS,而不是自行“自適應”調整(可能導致啟動過晚)。

      • 增加堆大小或老年代比例 (-Xmx,?-Xms,?-XX:NewRatio)。

      • 優化應用,減少對象創建和晉升速率、減小對象大小、避免過大的對象。

      • 增加 CMS 回收線程數 (-XX:ConcGCThreads?/?-XX:ParallelCMSThreads, 后者在較新版本已廢棄,推薦用?ConcGCThreads)。

  3. 對 CPU 資源敏感 (CPU Sensitive):

    • 原因:?并發標記和并發清除階段需要與應用線程爭搶 CPU 資源。

    • 后果:

      • 在 CPU 資源緊張(如 CPU 核數少、負載高)的情況下,并發回收線程會拖慢應用線程的執行速度,導致應用吞吐量下降

      • 并發階段本身可能因為 CPU 爭搶而執行得更慢,增加了并發模式失敗的風險。

    • 建議:?CMS 更適合?CPU 資源相對富余(核數較多或負載不高)的機器。

  4. 浮動垃圾 (Floating Garbage):?如前所述,并發過程中產生的垃圾只能在下一次 GC 回收。需要預留足夠空間容納這些浮動垃圾。

  5. 元空間/永久代觸發 Full GC:?CMS 不管理元空間 (Metaspace, JDK 8+) 或永久代 (PermGen, JDK 7-)。如果元空間/永久代空間不足,會觸發 Full GC。

  6. JDK 9+ 中已棄用 (Deprecated),JDK 14+ 中已移除 (Removed):

    • 棄用原因:?G1 作為更現代、設計更優的回收器(同樣追求低延遲,且解決了碎片問題)已成為默認選擇。CMS 的維護成本高,且其架構難以適應更新的 Java 特性和硬件發展(如非常大的堆)。

    • 后果:?在新版本 JDK (>=14) 中無法再使用 CMS。仍在使用的應用應盡快遷移到 G1 或其他回收器(如 ZGC, Shenandoah)。

五、關鍵配置參數

  • 啟用 CMS:

    • -XX:+UseConcMarkSweepGC?(JDK 8 及之前)

  • 設置年輕代收集器 (通常自動選擇):

    • 搭配 ParNew:-XX:+UseParNewGC?(通常啟用 CMS 會自動啟用)

  • 觸發 CMS 的堆占用閾值 (最重要!):

    • -XX:CMSInitiatingOccupancyFraction=<percent>?(e.g., 70): 當老年代空間占用達到此百分比時,啟動 CMS 并發收集周期。建議設低一些(如 50-70)以預防并發模式失敗。

  • 強制使用閾值觸發 (必須配!):

    • -XX:+UseCMSInitiatingOccupancyOnly:?強制?JVM 只使用?CMSInitiatingOccupancyFraction?的值作為觸發條件,禁用 JVM 的自適應調整。

  • 重新標記前進行 Young GC:

    • -XX:+CMSScavengeBeforeRemark: 在重新標記階段前強制觸發一次 Young GC,減少需要掃描的年輕代對象,有效縮短重新標記 STW 時間(強烈推薦啟用)。

  • CMS 線程數:

    • -XX:ConcGCThreads=<n>?/?-XX:ParallelCMSThreads=<n>?(后者較舊): 設置并發階段(標記、清除)使用的線程數。默認為?(ParallelGCThreads + 3) / 4。可根據 CPU 核數調整。

  • Full GC 后壓縮:

    • -XX:+UseCMSCompactAtFullCollection?(默認 true): Full GC 后進行壓縮。

    • -XX:CMSFullGCsBeforeCompaction=<n>?(默認 0): 執行 n 次不壓縮的 Full GC 后,執行一次帶壓縮的 Full GC。0?表示每次都壓縮。

六、何時使用(或曾經使用)CMS?

  • 歷史場景 (JDK 8 及之前):

    • 應用對老年代回收停頓時間非常敏感

    • 應用運行在中小型堆(如 4GB - 8GB)上。

    • 機器有富余的 CPU 資源(核數較多,負載不高)。

    • 應用能夠容忍一定程度的內存碎片或通過配置降低了 Full GC 風險。

    • 需要避免 Serial Old GC 的長停頓

  • 當前狀態:

    • JDK 9+:已棄用 (Deprecated)。

    • JDK 14+:已移除 (Removed)。

    • 強烈建議所有仍在使用 CMS 的應用遷移到?G1(目前默認且成熟)或探索新一代超低延遲回收器?ZGC?/?Shenandoah(尤其超大堆和極致低延遲需求)。

七、總結

CMS 垃圾回收器是 JVM 垃圾回收發展史上一個重要的里程碑,它率先通過并發標記清除的方式顯著降低了老年代回收的停頓時間,滿足了當時眾多對延遲敏感型 Java 應用的需求。其核心價值在于并發性帶來的低 STW 停頓

然而,CMS 的固有缺陷也非常明顯:

  1. 標記-清除算法導致內存碎片,?最終可能引發長時間的 Serial Old Full GC。

  2. 對并發模式失敗 (Concurrent Mode Failure) 非常敏感,?需要精細調優(尤其是?CMSInitiatingOccupancyFraction?和?UseCMSInitiatingOccupancyOnly)。

  3. 并發階段占用 CPU 資源,影響吞吐量。

  4. 無法管理元空間/永久代。

  5. 已被現代 JDK (>=14) 徹底移除。

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

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

相關文章

使用Java和iText庫填充PDF表單域的完整指南

PDF表單是企業和機構常用的數據收集工具&#xff0c;而通過編程方式自動填充PDF表單可以大大提高工作效率。本文將詳細介紹如何使用Java和iText庫來實現PDF表單的自動化填充。 為什么選擇iText庫&#xff1f; iText是一個強大的PDF操作庫&#xff0c;具有以下優勢&#xff1a…

跟著AI學習C#之項目實踐Day6

&#x1f4c5; Day 6&#xff1a;實現文章搜索功能&#xff08;Search System&#xff09; ? 今日目標&#xff1a; 實現按 標題、內容、作者 搜索文章使用 LINQ 構建動態查詢條件添加搜索框 UI 界面可選&#xff1a;使用全文搜索優化&#xff08;如 SQL Server 全文索引&am…

Learning to Prompt for Continual Learning

Abstract 持續學習背后的主流范式是使模型參數適應非平穩數據分布&#xff0c;其中災難性遺忘是核心挑戰。典型方法依賴于排練緩沖區或測試時已知的任務標識來檢索已學知識并解決遺忘問題&#xff0c;而這項工作提出了一種持續學習的新范式&#xff0c;旨在訓練一個更簡潔的記…

【論文閱讀筆記】知網SCI——基于主成分分析的空間外差干涉數據校正研究

論文詞條選擇 —— 知網 【SCI】【數據分析】 題目&#xff1a;基于主成分分析的空間外差干涉數據校正研究 原文摘要&#xff1a; 空間外差光譜技術(SHS)是一種新型的高光譜遙感探測技術&#xff0c;被廣泛應用于大氣觀測、天文遙感、物質識別等領域。通過空間外差光譜儀獲取…

如何用VS Code、Sublime Text開發51單片機

文章目錄 一、前置工作二、VS Code2.1 Code Runner配置2.2 編譯快捷鍵 三、Sublime Text3.1 Build System創建3.2 編譯快捷鍵 四、使用STC-ISP下載代碼到單片機 使用VS Code開發51單片機的好處自不必多說&#xff0c;直接進入正題。本博客的目標是讓你能夠使用VS Code或者Subli…

信息抽取數據集全景分析:分類體系、技術演進與挑戰_DEEPSEEK

信息抽取數據集全景分析&#xff1a;分類體系、技術演進與挑戰 摘要 信息抽取&#xff08;IE&#xff09;作為自然語言處理的核心任務&#xff0c;是構建知識圖譜、支持智能問答等應用的基礎。近年來&#xff0c;隨著深度學習技術的發展和大規模預訓練模型的興起&#xff0c;…

利用 Python 腳本批量查找并刪除指定 IP 的 AWS Lightsail 實例

在 AWS Lightsail 管理中&#xff0c;隨著實例數量的增多&#xff0c;我們常常會遇到這樣一個問題&#xff1a; “我知道某個公網 IP 地址&#xff0c;但不知道它關聯的是哪臺實例。” 或者&#xff1a; “我有一批老舊的實例只知道 IP&#xff0c;需要一鍵定位并選擇刪除。…

CompletableFuture 深度解析

本文將探討 Java 8 引入的 CompletableFuture&#xff0c;一個在異步編程中實現非阻塞、可組合操作的強大工具。我們將從 CompletableFuture 的基本概念、與傳統 Future 的區別、核心 API 用法&#xff0c;到復雜的鏈式調用、組合操作以及異常處理進行全面解析&#xff0c;并通…

給自己網站增加一個免費的AI助手,純HTML

助手效果圖 看完這篇文章&#xff0c;你將免費擁有你自己的Ai助手&#xff0c;全程干貨&#xff0c;先到先得 獲取免費的AI大模型接口 訪問這個地址 生成key https://openrouter.ai/mistralai/mistral-small-3.2-24b-instruct:free/api 或者調用其他的免費大模型&#xff0c;這…

ASProxy64.dll導致jetbrains家的IDE都無法打開。

在Windows11中,無法打開jetbrains的IDE的軟件,經過排查,發現與ASProxy64.dll有關。 E:\idea\IntelliJ IDEA 2024.1.7\bin>idea.bat CompileCommand: exclude com/intellij/openapi/vfs/impl/FilePartNodeRoot.trieDescend bool exclude = true # # A fatal error has bee…

springboot+Vue逍遙大藥房管理系統

概述 基于springbootVue開發的逍遙大藥房管理系統。該系統功能完善&#xff0c;既包含強大的后臺管理模塊&#xff0c;又具備用戶友好的前臺展示界面。 主要內容 一、后臺管理系統功能 ??核心管理模塊??&#xff1a; 用戶管理&#xff1a;管理員與普通用戶權限分級藥品分…

探索阿里云智能媒體管理IMM:解鎖媒體處理新境界

一、引言&#xff1a;開啟智能媒體管理新時代 在數字化浪潮的席卷下&#xff0c;媒體行業正經歷著前所未有的變革。從傳統媒體到新媒體的轉型&#xff0c;從內容生產到傳播分發&#xff0c;每一個環節都在尋求更高效、更智能的解決方案。而云計算&#xff0c;作為推動這一變革…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+jsp實現的新生報道管理系統,推薦!

摘要 隨著信息技術在管理上越來越深入而廣泛的應用&#xff0c;管理信息系統的實施在技術上已逐步成熟。本文介紹了新生報道管理系統的開發全過程。通過分析高校新生入學報到信息管理的不足&#xff0c;創建了一個計算機管理高校新生入學報到信息的方案。文章介紹了新生報道管…

給定一個整型矩陣map,求最大的矩形區域為1的數量

題目: 給定一個整型矩陣map,其中的值只有0和1兩種,求其中全是1的 所有矩形區域中,最大的矩形區域為1的數量。 例如: 1 1 1 0 其中,最大的矩形區域有3個1,所以返回3。 再如: 1 0 1 1 1 1 1 1 1 1 1 0 其中,最大的矩形區域有6個1,所以返回6。 解題思…

第8章-財務數據

get_fund # 查看股票代碼000001.XSHE在2022年9月1日的總市值 q query( valuation ).filter( valuation.code 000001.XSHE ) df get_fundamentals(q, 2022-09-01) print(df[market_cap][0]) # 獲取第一行的market_cap值 這段代碼看起來是用于查詢股票在特定日期的總…

SQL關鍵字三分鐘入門:ROW_NUMBER() —— 窗口函數為每一行編號

在進行數據分析時&#xff0c;我們常常需要為查詢結果集中的每條記錄生成一個唯一的序號或行號。例如&#xff1a; 為每位員工按照入職時間排序并編號&#xff1b;按照訂單金額對訂單進行排序&#xff0c;并給每個訂單分配一個順序編號&#xff1b;在分組數據內為每條記錄編號…

微信小程序如何實現通過郵箱驗證修改密碼功能

基于騰訊云開發&#xff08;Tencent Cloud Base&#xff09;實現小程序郵箱驗證找回密碼功能的完整邏輯說明及關鍵代碼實現。結合安全性和開發效率&#xff0c;方案采用 ??云函數 小程序前端?? 的架構&#xff0c;使用 ??Nodemailer?? 發送郵件。Nodemailer 是一個專為…

C# VB.NET中Tuple輕量級數據結構和固定長度數組

C# VB.NET取字符串中全角字符數量和半角字符數量-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148871910 在VB.NET中&#xff0c;使用Tuple和固定長度數組在性能上有細微差異&#xff0c;以下是詳細分析&#xff1a; 性能對比測試 通過測試 100 萬次調用&am…

建筑物年代預測與空間異質性分析解決方案

建筑物年代預測與空間異質性分析解決方案 1. 問題分析與創新點設計 核心任務:預測建筑物建造年代,并分析空間異質性對預測的影響 創新點設計: 空間權重矩陣集成:構建空間鄰接矩陣量化地理鄰近效應多尺度特征提取:融合建筑物微觀特征與街區宏觀特征異質性分區建模:基于…

FOUPK3system5XOS

Foupk3systemX5OS系統19.60內測版&#xff08;X9&#xff09;2023年4月16日正式發布 1.0Foupk3systemX5OS系統19.60&#xff08;X9&#xff09;2024年10月6日發布 Foupk3systemX5OS系統19.60增強版&#xff08;X9X5&#xff09;2024年10月6日發布Foupk3systemX5OS系統19.60正…