垃圾收集算法與收集器

在 JVM 中,垃圾收集(Garbage Collection, GC)算法的核心目標是自動回收無用對象的內存,同時盡量減少對應用性能的影響。以下是 JVM 中主要垃圾收集算法的原理、流程及實際應用場景的詳細介紹:


一、標記-清除算法(Mark-Sweep)

原理
  • 標記階段:從 GC Roots(如棧引用、靜態變量)出發,遍歷對象圖,標記所有存活對象。
  • 清除階段:掃描堆內存,回收未被標記的對象所占用的內存(直接釋放,不整理內存)。
工作流程
  1. 暫停所有應用線程(STW,Stop-The-World),啟動標記。
  2. 標記完成后,清除未標記的垃圾對象。
  3. 恢復應用線程。
優點
  • 實現簡單,內存回收效率較高。
缺點
  • 內存碎片化:清除后會產生不連續的內存空間,可能無法分配大對象,最終觸發 Full GC。
  • 兩次 STW:標記和清除階段均需暫停應用線程。
應用場景
  • CMS 收集器的老年代回收(僅清除階段,標記階段并發執行)。

二、標記-整理算法(Mark-Compact)

原理
  • 標記階段:與標記-清除相同,標記所有存活對象。
  • 整理階段:將所有存活對象向內存一端移動,清理邊界外的內存(消除碎片)。
工作流程
  1. STW 標記存活對象。
  2. 將存活對象移動到內存一端,保持連續。
  3. 清除邊界外的內存。
  4. 恢復應用線程。
優點
  • 無內存碎片:整理后內存連續,適合長期運行的應用。
  • 空間利用率高:減少大對象分配失敗的概率。
缺點
  • 兩次 STW 且時間長:移動對象需要額外時間,尤其是堆較大時。
  • 內存移動開銷:對象復制可能影響吞吐量。
應用場景
  • Serial OldParallel Old 收集器的老年代回收。
  • G1 的混合回收階段(復制存活對象到新 Region)。

三、復制算法(Copying)

原理
  • 將堆內存分為兩塊(From 和 To 空間),每次只使用其中一塊。
  • 存活對象復制:將 From 空間的存活對象復制到 To 空間,并保持緊湊排列。
  • 清空 From 空間:復制完成后,直接清空 From 空間。
工作流程
  1. STW 標記 From 空間的存活對象。
  2. 將存活對象按順序復制到 To 空間。
  3. 交換 From 和 To 空間的角色。
  4. 恢復應用線程。
優點
  • 無碎片:對象在 To 空間連續排列。
  • 高效回收:只需遍歷存活對象,適合存活率低的場景。
缺點
  • 內存浪費:需預留一半內存作為復制空間,實際可用內存僅 50%。
  • 存活率高時效率低:若多數對象存活,復制成本高。
應用場景
  • 年輕代回收(如 Serial、ParNew、Parallel Scavenge 收集器)。
  • G1 的年輕代 Region 回收

四、分代收集算法(Generational Collection)

核心思想

基于對象的生命周期特性,將堆劃分為不同區域(年輕代、老年代),對不同代采用不同算法:

  1. 年輕代:對象存活率低,使用復制算法
  2. 老年代:對象存活率高,使用標記-清除標記-整理算法。
分代依據
  • 弱分代假說(Weak Generational Hypothesis):絕大多數對象朝生夕死。
  • 強分代假說(Strong Generational Hypothesis):多次存活的對象傾向于繼續存活。
工作流程
  1. 年輕代 Minor GC:頻繁觸發,使用復制算法回收 Eden 和 Survivor 區。
  2. 老年代 Major GC/Full GC:觸發頻率低,使用標記-清除或標記-整理算法。
應用場景
  • 所有現代 JVM 收集器的默認策略(如 CMS、G1、ZGC 等)。

五、增量收集算法(Incremental Collecting)

原理
  • 將垃圾回收過程分為多個小步驟,與應用線程交替執行。
  • 每次僅回收部分垃圾,減少單次 STW 時間。
優點
  • 降低延遲:每次暫停時間短,適合實時性要求高的場景。
缺點
  • 總體吞吐量下降:頻繁切換線程導致額外開銷。
  • 實現復雜:需處理應用線程與回收線程的交互。
應用場景
  • CMS 的并發標記階段(并發執行,但需最終 STW 修正)。
  • Shenandoah 收集器(并發復制對象)。

六、分區收集算法(Region-Based)

原理
  • 將堆劃分為多個獨立區域(Region),優先回收垃圾比例高的區域(Garbage-First 原則)。
  • 結合分代思想,動態分配區域角色(Eden、Survivor、Old)。
優點
  • 可預測停頓:通過控制每次回收的區域數量,滿足 MaxGCPauseMillis 目標。
  • 高效管理大堆:避免全堆掃描,減少 STW 時間。
應用場景
  • G1 收集器:分 Region 管理,混合回收年輕代和老年代。
  • ZGC/Shenandoah:基于類似思想,擴展為全堆并發回收。

七、算法對比與選型

算法優點缺點適用場景
標記-清除實現簡單,無移動開銷內存碎片,兩次 STW老年代(CMS)
標記-整理無碎片,空間利用率高STW 時間長,移動開銷大老年代(Serial Old)
復制無碎片,回收效率高內存浪費,存活率高時低效年輕代(所有分代收集器)
分代收集結合對象生命周期優化需維護分代結構所有現代收集器
增量收集低延遲吞吐量下降實時系統(Shenandoah)
分區收集可預測停頓,大堆友好元數據管理復雜G1、ZGC、Shenandoah

總結

JVM 的垃圾收集算法是內存管理的核心,不同算法在吞吐量延遲內存開銷之間權衡。實際應用中,分代收集與分區算法(如 G1)成為主流,而 ZGC/Shenandoah 進一步通過并發和壓縮技術突破停頓時間限制。選擇算法需結合應用場景(如堆大小、延遲要求)及 JVM 版本特性。


以下以CMS和G1垃圾收集器的原理與工作流程舉例:

CMS(Concurrent Mark-Sweep)收集器

設計目標
  • 低延遲:通過并發標記和清除減少停頓時間(STW),適用于對響應時間敏感的應用(如Web服務)。
  • 老年代專用:僅管理老年代,需與年輕代收集器(如ParNew)配合使用。

核心原理
  1. 標記-清除算法
    • 通過標記存活對象,直接清除未標記的垃圾對象,不進行內存整理,可能導致內存碎片。
  2. 并發執行
    • 大部分垃圾回收階段與應用線程并發執行,減少STW時間。

工作流程(4個階段)
  1. 初始標記(Initial Mark)

    • STW:短暫暫停,標記從GC Roots直接可達的對象(如棧引用、靜態變量)。
    • 依賴年輕代回收:通常與年輕代的Minor GC同步觸發,避免全堆掃描。
  2. 并發標記(Concurrent Mark)

    • 并發執行:遍歷老年代對象圖,標記所有存活對象(與應用線程并行)。
    • 可能漏標:并發階段應用線程可能修改對象引用,需后續修正。
  3. 重新標記(Remark)

    • STW:修正并發標記期間因應用線程運行導致的標記變化(使用增量更新或原始快照算法)。
    • 時間較長:需處理所有變更,是CMS中最耗時的STW階段。
  4. 并發清除(Concurrent Sweep)

    • 并發執行:清除未標記的垃圾對象,回收內存空間。
    • 不整理內存:清除后產生內存碎片,需定期Full GC(使用Serial Old)進行壓縮。

關鍵問題
  • 內存碎片:長期運行后可能觸發Full GC,導致長時間停頓。
  • 浮動垃圾:并發階段新產生的垃圾需等到下次回收。
  • CPU競爭:并發階段占用CPU資源,可能影響應用吞吐量。

G1(Garbage-First)收集器

設計目標
  • 平衡吞吐量與延遲:通過分Region和可預測停頓,適應大堆內存(4GB+)場景。
  • 全堆管理:統一管理年輕代和老年代,動態分配Region角色。

核心原理
  1. 分Region模型

    • 堆被劃分為多個大小固定(1MB~32MB)的Region,每個Region可以是Eden、Survivor或Old類型。(堆/2048)
    • Humongous區域:存儲大于Region 50%的大對象。
  2. 標記-整理算法

    • 通過復制存活對象到新Region,避免內存碎片。
  3. 停頓預測模型

    • 根據用戶設定的MaxGCPauseMillis,優先回收垃圾比例高的Region(Garbage-First原則)。

工作流程(3種操作模式)

G1的回收過程分為三種操作:年輕代回收(Young GC)并發標記周期(Concurrent Marking Cycle)混合回收(Mixed GC)


1. 年輕代回收(Young GC)
  • STW:暫停所有應用線程,復制Eden和Survivor區的存活對象到新Survivor或Old Region。
  • 觸發條件:Eden區占滿時觸發。

2. 并發標記周期(Concurrent Marking Cycle)
  1. 初始標記(Initial Mark)

    • STW:標記GC Roots直接可達的對象(與Young GC同步觸發,復用Young GC的暫停)。
  2. 根區域掃描(Root Region Scan)

    • 掃描Survivor區(作為GC Roots的一部分),確保并發標記的正確性。
  3. 并發標記(Concurrent Mark)

    • 并發執行:遍歷堆中所有存活對象,標記存活狀態。
  4. 最終標記(Final Mark)

    • STW:處理SATB(Snapshot-At-The-Beginning)隊列中的引用變更,確保標記準確性。
  5. 清除階段(Cleanup)

    • 部分STW:統計各Region的垃圾比例,識別高價值回收區域。
    • 不回收內存:僅選擇待回收的Region,為混合回收做準備。

3. 混合回收(Mixed GC)
  • STW:同時回收年輕代和部分老年代Region(根據垃圾比例選擇)。
  • 多次執行:可能分多次回收,直到滿足MaxGCPauseMillis目標。

關鍵優勢
  • 內存整理:通過復制算法避免碎片。
  • 可預測停頓:動態調整回收的Region數量以滿足停頓目標。
  • 大堆優化:分Region設計適合管理超大堆內存。

CMS與G1對比

特性CMSG1
堆結構傳統分代(年輕代+老年代)分Region,邏輯分代
算法標記-清除(碎片需Full GC整理)標記-整理(復制算法,無碎片)
停頓控制不可預測通過MaxGCPauseMillis預測
適用場景中小堆,低延遲優先大堆(4GB+),平衡吞吐量和延遲
內存開銷較高(Region元數據)
Full GC觸發內存不足/碎片時觸發Serial Old盡量避免,依賴并發周期
JDK支持已廢棄(JDK 14移除)JDK 9+默認

總結

  • CMS:通過并發標記-清除減少停頓,適合中小堆且延遲敏感的場景,但面臨碎片和Full GC風險。
  • G1:分Region模型和可預測停頓設計,適合大堆內存,平衡吞吐量與延遲,是JDK 9+的默認選擇。

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

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

相關文章

如何為服務設置合理的線程數

1. 首先,要確定最大線程數的限制因素。通常,線程數量受限于內存、CPU和操作系統限制。比如,每個線程都需要一定的棧內存,默認情況下Java線程的棧大小是1MB(64位系統可能更大),所以如果內存不足&…

內容中臺:元數據驅動管理新范式

元數據驅動智能管理中樞 現代企業內容管理正經歷從碎片化存儲向結構化治理的范式轉變,元數據驅動機制在此過程中展現出核心樞紐價值。通過構建多維屬性標簽體系,Baklib等內容中臺解決方案實現了對文本、音視頻等數字資產的精準定義,其動態分…

在mac中設置環境變量

步驟一:打開終端 步驟二:輸入printenv,查看當前已有的環境變量; 步驟三:輸入:nano ~/.zshrc 打開環境變量編輯頁面; 步驟四:輸入新的變量:export DEEPSEEK_API_KEY&qu…

擴散模型的算法原理及其在圖像生成領域的優勢與創新

目錄 一、引言 二、擴散模型的加噪過程 (一)前向擴散過程 (二)噪聲調度策略 三、擴散模型的去噪過程 (一)反向擴散過程 (二)去噪網絡架構 四、擴散模型的訓練和推理機制 &am…

技術領域,有許多優秀的博客和網站

在技術領域,有許多優秀的博客和網站為開發者、工程師和技術愛好者提供了豐富的學習資源和行業動態。以下是一些常用的技術博客和網站,涵蓋了編程、軟件開發、數據科學、人工智能、網絡安全等多個領域: 1. 綜合技術博客 1.1 Medium 網址: ht…

mysql經典試題共34題

1、準備數據 -- drop drop table if exists dept; drop table if exists emp; drop table if exists salgrade;-- CREATE CREATE TABLE dept (deptno int NOT NULL COMMENT 部門編號,dname varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMM…

2025 - GDB 盲調筆記--調試 “無調試符號“ “無調試信息“ 的三方程序

環境: arm64-ubuntu 相關:strace、ltrace、readelf、patchelf、strings、ldd -v 1). 使用 gdb 啟動目標程序(不能直接用gdb啟動的,可以先單獨啟動,再 gdb attach 強制調試) DIR_APP/opt/test gdb --args env LANGUAGE LD_LIBRA…

OCPP擴展機制與自定義功能開發:協議靈活性設計與實踐 - 慧知開源充電樁平臺

OCPP擴展機制與自定義功能開發:協議靈活性設計與實踐 引言 OCPP作為開放協議,其核心價值在于平衡標準化與可擴展性。面對不同充電樁廠商的硬件差異、區域能源政策及定制化業務需求,OCPP通過**擴展點(Extension Points&#xff09…

【項目】nnUnetv2復現

作者提出一種nnUNet(no-new-Net)框架,基于原始的UNet(很小的修改),不去采用哪些新的結構,如相殘差連接、dense連接、注意力機制等花里胡哨的東西。相反的,把重心放在:預處理(resampling和normalization)、訓練(loss,optimizer設置、數據增廣)、推理(patch-based…

代碼隨想錄算法訓練營第八天|Leetcode 151.翻轉字符串里的單詞 卡碼網:55.右旋轉字符串 字符串總結 雙指針回顧

151.翻轉字符串里的單詞 建議:這道題目基本把 剛剛做過的字符串操作 都覆蓋了,不過就算知道解題思路,本題代碼并不容易寫,要多練一練。 題目鏈接/文章講解/視頻講解:代碼隨想錄 我們這道題的思路是,先將整…

【計算機網絡】計算機網絡的性能指標——時延、時延帶寬積、往返時延、信道利用率

計算機網絡的性能指標 導讀 大家好,很高興又和大家見面啦!!! 在上一篇內容中我們介紹了計算機網絡的三個性能指標——速率、帶寬和吞吐量。用大白話來說就是:網速、最高網速和實時網速。 相信大家看到這三個詞應該就…

Refreshtoken 前端 安全 前端安全方面

網絡安全 前端不需要過硬的網絡安全方面的知識,但是能夠了解大多數的網絡安全,并且可以進行簡單的防御前兩三個是需要的 介紹一下常見的安全問題,解決方式,和小的Demo,希望大家喜歡 網絡安全匯總 XSSCSRF點擊劫持SQL注入OS注入請求劫持DDOS 在我看來,前端可以了解并且防御前…

vue3框架的響應式依賴追蹤機制

當存在一個響應式變量于視圖中發生改變時會更新當前組件的所以視圖顯示,但是沒有視圖中不寫這個響應式變量就就算修改該變量也不會修改視圖,這是為什么?我們能否可以理解寬泛的理解為vue組件的更新就是視圖的更新,單當視圖中不存在…

C#核心(22)string

前言 我們在之前的學習中已經學習過了很多數字類型的數據結構,但一直沒有講解除了char以外的字符串相關的知識點,這也是我們繼繼承,封裝,重載這些知識點之后要補充講解的核心知識點。 你也發現了,其實在密封函數之后我們就已經開始進入更底層的方面為你講解知識點了,這…

Spring Boot 本地緩存工具類設計與實現

在 Spring Boot 應用中,緩存是提升性能的重要手段之一。為了更方便地使用緩存,我們可以設計一套通用的本地緩存工具類,封裝常見的緩存操作,簡化開發流程。本文將詳細介紹如何設計并實現一套 Spring Boot 本地緩存工具類&#xff0…

引領變革!北京愛悅詩科技有限公司榮獲“GAS消費電子科創獎-產品創新獎”!

在2025年“GAS消費電子科創獎”評選中,北京愛悅詩科技有限公司提交的“aigo愛國者GS06”,在技術創新性、設計創新性、工藝創新性、智能化創新性及原創性五大維度均獲得評委的高度認可,榮獲“產品創新獎”。 這一獎項不僅是對愛悅詩在消費電子…

考研英語語法全攻略:從基礎到長難句剖析?

引言 在考研英語的備考之旅中,語法猶如一座燈塔,為我們在浩瀚的英語知識海洋中指引方向。無論是閱讀理解中復雜長難句的解讀,還是寫作時準確流暢表達的需求,扎實的語法基礎都起著至關重要的作用。本文將結合有道考研語法基礎入門課的相關內容,為大家全面梳理考研英語語法…

構建自己的AI客服【根據用戶輸入生成EL表達式】

要實現一個基于對話形式的AI客服系統,該系統能夠提示用戶輸入必要的信息,并根據用戶的輸入生成相應的EL(Expression Language)表達式編排規則,您可以按照以下步驟進行設計和開發。本文將涵蓋系統架構設計、關鍵技術選型…

【JavaWeb12】數據交換與異步請求:JSON與Ajax的絕妙搭配是否塑造了Web的交互革命?

文章目錄 🌍一. 數據交換--JSON??1. JSON介紹??2. JSON 快速入門??3. JSON 對象和字符串對象轉換??4. JSON 在 java 中使用??5. 代碼演示 🌍二. 異步請求--Ajax??1. 基本介紹??2. JavaScript 原生 Ajax 請求??3. JQuery 的 Ajax 請求 &a…

解決CentOS 8.5被惡意掃描的問題

CentOS 8 官方倉庫已停止維護(EOL),導致一些常用依賴包如fail2ban 無法正常安裝。 完整解決方案: 一、問題根源 CentOS 8 官方倉庫已停更:2021 年底 CentOS 8 停止維護,默認倉庫的包可能無法滿足依賴關系。EPEL 倉庫兼容性:EPEL 倉庫可能未適配 CentOS 8.5 的舊版本依賴…