【從零學習JVM|第九篇】常見的垃圾回收算法和垃圾回收器

前言:

我們知道在堆內存中,會有自動的垃圾回收功能,那今天這篇文章將會向你介紹,這個功能實現的方式,還有實現的對象,接下來就由我來給你們詳細介紹垃圾回收的算法和實現算法的回收器。

目錄

前言:

常見的四種垃圾回收算法

標記清除算法

核心思想

實現過程兩個階段

使用場景

標記整理算法

核心思想

實現過程

使用場景

復制算法

核心思想

實現過程

?使用場景

分代gc算法

核心思想

Minor GC 前的決策流程

?關鍵步驟詳解

檢查1:老年代空間 > 新生代總大小

檢查2:老年代空間 > 歷史平均晉升大小

檢查失敗:直接觸發 Full GC

常見垃圾回收器

年輕代垃圾回收器(Minor GC)

1. Serial 收集器

2. ParNew 收集器

3. Parallel Scavenge 收集器

老年代垃圾回收器(Major GC/Full GC)

1. Serial Old 收集器

2. Parallel Old 收集器

3. CMS(Concurrent Mark-Sweep)收集器

G1垃圾回收器

G1 的垃圾回收過程

主要優點

主要缺點

不適用場景

總結


常見的四種垃圾回收算法

標記清除算法

核心思想

通過?可達性分析?標記存活對象,直接回收未標記對象的內存

實現過程兩個階段
  1. 標記階段(STW)

    • 從 GC Roots(棧引用、靜態變量等)出發,遞歸遍歷對象圖。

    • 對存活對象打標記。

  2. 清除階段(STW)

    • 線性掃描堆內存。

    • 回收未標記對象的內存塊(加入空閑鏈表)。

優點:實現簡單,第一階段標記,第二階段清除。

缺點:

  • 碎片化內存:內存是連續的,如果在對象被刪除之后,就會出現很多細小的內存,如果我們需要很大的內存空間,那么就很可能無法匹配。

很明顯,無法做到,因為紅色的就是空閑內存但是最大的才4個字節。

  • 分配速度慢:內存碎片化,所以在回收內存之后,會把這段空閑內存加入一個空閑鏈表,每次分配內存都會遍歷整個鏈表找到合適的位置。
使用場景
  • 老年代回收:CMS 收集器的回收基礎

  • 大對象堆:對象存活率高,移動成本大

  • 嵌入式系統:資源受限環境(如 RTOS)

標記整理算法

核心思想

在標記存活對象后,移動對象消除碎片,使空閑內存連續。我們可以把它看作是基于標記清除的一個處理碎片化內存的算法。

實現過程
  1. 標記階段

    • 從 GC Roots(棧引用、靜態變量等)出發,遞歸遍歷對象圖。

    • 對存活對象打標記。

  2. 整理階段(STW)

    • 滑動整理:將存活對象“滑動”到內存一端。

    • 清理:清理掉沒有存活對象。

優點:

  • 內存的使用效率高。
  • 沒有碎片化內存。

缺點:

  • 整理階段效率不高,效率是低于標記清除算法的
使用場景
  • 老年代回收:Serial Old, Parallel Old, ZGC

  • 低碎片需求:實時系統、長期運行服務

  • 內存敏感場景:Android ART 的 Foreground GC

復制算法

核心思想

將內存分為兩等份,只使用其中一份;GC 時將存活對象復制到另一份空間,清空原空間。

實現過程
  1. 內存劃分:堆分為?From 區(當前使用)和?To 區(空閑),創建對象時都只在From區。

  2. 垃圾回收階段(STW)

    • 從 GC Roots 遍歷存活對象

    • 將存活對象復制到 To 區(保持緊湊排列),刪除from區對象

    • 交換 From/To 區角色

優點:

  • 不會發生碎片化
  • ?回收高效(僅處理存活對象)

缺點:

  • 內存使用率低,每次只使用一半的內存
  • 對象復制開銷大
?使用場景
  • 年輕代回收:HotSpot 的 Serial/ParNew/Parallel Scavenge

  • 短命對象場景:對象存活率 < 10% 時最優

  • 小內存區域:JVM 的 Survivor 區

分代gc算法

現代優秀的垃圾回收算法,會將上面的幾種垃圾回收算法組合使用,其中應用最廣的就是分代垃圾回收。

核心思想

基于 對象的存活時間長久將堆劃分為年輕代(活得短),老年代(活得長),對每代應用不同算法。

年輕代:

  • 分為Eden區用于存儲新創建的對象。
  • 幸存者區:這里方便觀察,分為S0和S1,這個區使用復制算法進行垃圾回收。

實現過程:

  1. 年輕代(Young Generation)

    • 算法復制算法

    • 過程(剛剛創建時)

      • 對象分配在 Eden

      • Eden 滿時觸發?Minor GC
        存活對象復制到 Survivor 區中的To區,然后修改交換From與To區

  2. 老年代(Old Generation)

    • 算法標記清除?或?標記整理

    • 觸發:空間不足時啟動?Full GC

詳細過程(第一次創建對象):剛創建的對象會放在Eden區,然后當Eden滿了,新創建的對象已經放不進去了,就會觸發第一次Minor GC清理垃圾,隨后把存活的對象放入,幸存者To區。隨后把From和To區交換。

在接下來的對象就又可以放入Eden區。

隨后Eden區又滿了,這個時候就會再次觸發Minor GC,此時From區和Eden區都會進行垃圾清理,把存活下的對象放入To區(復制算法)。

那老年代中的對象是怎么放進去的呢?

其實在每一次Minor GC后都會使存活下的對象年齡+1,年齡初始值為0,當年齡達到閾值(最大值15,跟垃圾回收器的種類有關。)就會成功晉升到老年代存儲。

進入老年代的條件:

  • 當年齡達到閾值
  • 當幸存者區中的To區無法容納新的對象時,To區中的對象不管年齡多少都會放入,老年代

其實我們要清楚,每次觸發Minor GC后都有可能會晉升對象到老年代,那如果老年代空間不夠咋辦。下面Minor GC的詳細過程過程。

Minor GC 前的決策流程

?關鍵步驟詳解
檢查1:老年代空間 > 新生代總大小
  • 目的:確保老年代能容納最壞情況(整個新生代對象全部存活晉升)

  • 通過條件Old Free > Eden + Survivor

  • 結果:安全執行 Minor GC

檢查2:老年代空間 > 歷史平均晉升大小
  • 目的:基于歷史數據預測本次晉升風險

  • 通過條件Old Free > Avg(Promoted)

  • 結果冒險執行 Minor GC

    • JVM 會嘗試 Minor GC,但已準備好后備方案

    • 若晉升時老年代空間不足 →?立即觸發 Full GC

檢查失敗:直接觸發 Full GC
  • 條件Old Free < Avg(Promoted)

  • 結果:跳過本次 Minor GC,直接 Full GC

Full GC:同時清理年輕代和老年代

兩次判斷:本質上也是判斷老年代空間還夠不夠

歷史平均晉升大小:把每次晉升的對象大小加起來/個數得到平均大小。

默認情況下年輕代大小遠小于老年代

最后如果觸發了Full Gc之后還是無法存儲我們的新對象,就會OOM。

常見垃圾回收器

垃圾回收器就是垃圾回收算法的具體實現。垃圾回收器分為年輕代和老年代,所以必須成對使用。

年輕代垃圾回收器(Minor GC)

1. Serial 收集器
  • 算法復制算法(單線程)

  • 工作方式

    • 觸發 Minor GC 時暫停所有應用線程(Stop-The-World

    • 單線程完成存活對象標記、復制到 Survivor 區/老年代

  • 適用場景

    • 客戶端模式(如桌面應用)

    • 單核服務器或小內存應用(<100MB)

  • 優點:實現簡單,無線程交互開銷

  • 缺點:STW 停頓明顯

2. ParNew 收集器
  • 算法復制算法(多線程并行)

  • 工作方式

    • Serial 的多線程版本,需與 CMS 搭配使用

    • 多線程并行執行標記和復制(線程數通過?-XX:ParallelGCThreads?控制)

  • 適用場景

    • 需與 CMS 配合的服務端應用(如 Web 服務)

  • 優點:縮短年輕代 STW 時間

  • 缺點:在單核環境下性能可能不如 Serial

3. Parallel Scavenge 收集器
  • 算法復制算法(多線程并行)

  • 核心目標最大化吞吐量

  • 關鍵參數(可以手動配置)

    • -XX:MaxGCPauseMillis:最大 GC 停頓時間目標(不保證)

    • -XX:GCTimeRatio:吞吐量目標(默認 99%,即 GC 時間占比 ≤1%)

  • 適用場景

    • 后臺計算、批處理任務(如大數據分析)

  • 優點:吞吐量優先,自適應調節堆大小

  • 缺點:停頓時間不穩定

它是JDK8默認的年輕代垃圾回收器,關注吞吐量,可以自動調節堆內存的大小。

老年代垃圾回收器(Major GC/Full GC)

1. Serial Old 收集器
  • 算法標記-整理算法(單線程)

  • 工作方式

    • 單線程 STW 執行標記、整理(壓縮內存消除碎片)

  • 用途

    • 客戶端模式下的老年代回收

    • 作為 CMS 失敗時的后備方案

2. Parallel Old 收集器
  • 算法標記-整理算法(多線程并行)

  • 工作方式

    • Parallel Scavenge 的老年代搭檔

    • 多線程并行標記和整理

  • 目標與 Parallel Scavenge 協同最大化吞吐量

  • 適用場景

    • 高吞吐量要求的服務端應用(如數據倉庫)

3. CMS(Concurrent Mark-Sweep)收集器
  • 算法標記-清除算法(并發執行)

  • 目標最小化暫停時間

  • 執行流程

    1. 初始標記(STW):標記 GC Roots 直接關聯的對象(速度快)

    2. 并發標記(與應用并行):遍歷對象圖

    3. 重新標記(STW):修正并發標記期間的引用變化

    4. 并發清除(與應用并行):回收垃圾

  • 優點:大部分工作并發執行,停頓時間短

  • 缺點

    • 內存碎片:需定期 Full GC(Serial Old)整理

    • CPU 敏感:并發階段占用線程資源

    • 浮動垃圾:并發清理時新產生的垃圾需下次回收

G1垃圾回收器

JDK9之后的默認垃圾回收器,Parallel Scavenge關心吞吐量,CMS關心最大暫停時間,G1的設計就是把他們的優點進行融合。

G1的整個堆被劃分為多個相同大小的區域,稱為Region,區域不要求連續,分為Eden,Survivor,Old區,Region的大小通過堆空間大小/2048的到。

G1 的垃圾回收過程

G1 的回收過程分為以下四個階段,部分階段需要 “Stop The World”(STW):

  1. 初始標記(Initial Mark)

    • STW 階段,標記 GC Roots 直接引用的對象。
    • 耗時短,僅需掃描根對象和年輕代的 Region。
  2. 并發標記(Concurrent Mark)

    • 與應用程序并發執行,從 GC Roots 開始遍歷所有可達對象。
    • 過程中會記錄對象圖的變化(通過 SATB 算法),避免漏標。
  3. 重新標記(Remark)

    • STW 階段,處理并發標記期間的對象圖變化,確保標記完整性。
    • 采用增量更新算法,耗時比 CMS 更短。
  4. 篩選回收(Cleanup & Evacuation)

    • 計算每個 Region 的垃圾占比,根據停頓時間目標選擇價值最高的 Region 進行回收。
    • 移動存活對象到新 Region,釋放舊 Region 空間,實現內存整理(無碎片化)。
主要優點
  1. 可預測的低延遲

    • 通過-XX:MaxGCPauseMillis參數控制最大停頓時間,優先回收價值高的 Region,避免全堆掃描。
    • 相比 CMS 的 "標記 - 清除" 算法,G1 的 "標記 - 整理" 算法避免了內存碎片化,減少 Full GC 頻率。
  2. 分代與分區的結合

    • 邏輯上分代(年輕代 / 老年代),物理上分區(Region),靈活性高。
    • 大對象直接分配到 Humongous Region,避免頻繁晉升導致的性能損耗。
  3. 并行與并發處理

    • 標記階段與應用線程并發執行,減少 STW 時間。
    • 回收階段采用多線程并行處理,提升效率。
  4. 大內存處理能力

    • 對于堆內存超過 4GB 的應用,G1 的分區設計使其管理效率顯著高于 CMS 和 Parallel GC。
主要缺點
  1. 內存占用開銷

    • 為實現精確的停頓控制,G1 需要維護 Remembered Set 和 Card Table 等數據結構,增加約 10%-15% 的內存開銷。
  2. 算法復雜度高

    • 相比 Parallel GC,G1 的算法更復雜,在小內存場景下可能不如傳統回收器高效。
不適用場景
  1. 小內存應用(堆內存 < 2GB)

    • 此時 G1 的內存開銷和算法復雜度可能導致性能不如 Serial 或 Parallel GC。
  2. 吞吐量優先的批處理應用

    • 如數據挖掘、科學計算等,對延遲要求不高,Parallel GC 可能更合適。
  3. 單線程環境

    • G1 的多線程并行優勢無法發揮,Serial GC 可能更輕量。

總結:G1 垃圾回收器是現代 Java 應用的首選 GC 方案,尤其適合大內存、低延遲的場景。其核心價值在于通過分區設計和可預測的停頓控制,平衡了吞吐量和響應時間。但在實際應用中,需根據堆內存大小、處理器資源和業務特性合理配置參數,以達到最優性能。

G1垃圾回收器不管是老年代還是年輕代都可以使用,所以不需要搭配使用。

在JDK9的版本之后默認就是它所以也建議使用它。

Region Size必須是2的指數冪,取值范圍1M-32M

總結

本文介紹了常見的垃圾回收算法和常見的垃圾回收器,對于他們的優點缺點和使用場景做了一定的介紹,希望通過本篇文章,你可以有所收獲。

感謝你的閱讀,創作不易,如果對你有幫助希望點贊收藏加轉發

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

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

相關文章

品牌竄貨治理解決方案

在渠道網絡的暗潮中&#xff0c;竄貨猶如隱秘的漩渦&#xff0c;某知名白酒品牌曾因區域竄貨導致終端價格體系崩潰&#xff0c;半年內損失超3億元。竄貨行為不僅破壞市場秩序&#xff0c;更會引發信任危機。隨著電商平臺的多元化與分銷層級的復雜化&#xff0c;品牌方亟需構建一…

車載電子電器架構 --- 法律和標準對電子電氣架構的影響

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

一種通用跨平臺實現SEH的解決方案

一. 前言 眾所周知&#xff0c;在軟件的代碼中&#xff0c;處理軟件本身的邏輯只要大約1/3的代碼&#xff0c;另外2/3的代碼實際上是在處理各種各樣的異常情況。 這些異常情況一方面是因為不同用戶之間不同的硬件軟件環境要處理。另一方面是程序中可能出現的bug。比較典型的情…

25.6.19學習總結

什么是堆&#xff08;Heap&#xff09;&#xff1f; 堆是一種特殊的樹形數據結構&#xff0c;它滿足以下兩個主要屬性&#xff1a; 結構性&#xff08;完全二叉樹&#xff09;&#xff1a; 堆總是一個完全二叉樹 (Complete Binary Tree)。這意味著&#xff0c;除了最后一層&am…

【前后前】導入Excel文件閉環模型:Vue3前端上傳Excel文件,【Java后端接收、解析、返回數據】,Vue3前端接收展示數據

【前后前】導入Excel文件閉環模型&#xff1a;Vue3前端上傳Excel文件&#xff0c;【Java后端接收、解析、返回數據】&#xff0c;Vue3前端接收展示數據 一、Vue3前端上傳&#xff08;導入&#xff09;Excel文件 ReagentInDialog.vue <script setup lang"ts" na…

網絡基礎入門:從OSI模型到TCP/IP協議詳解

網絡基礎入門&#xff1a;從OSI模型到TCP/IP協議詳解 一、網絡基礎概念與OSI七層模型 1.1 網絡通信的本質 計算機網絡的核心是將抽象語言轉換為二進制數據進行傳輸與計算&#xff0c;這一過程涉及多層抽象與轉換&#xff1a; 應用層&#xff1a;人機交互—抽象語言------編…

Linux致命漏洞CVE-2025-6018和CVE-2025-6019

Qualys 最近披露了兩個影響主流 Linux 發行版的本地權限提升 (LPE) 漏洞&#xff0c;分別是 CVE-2025-6018 和 CVE-2025-6019。這兩個漏洞可以被串聯利用&#xff0c;使得非特權用戶在幾秒鐘內獲得系統的 root 權限&#xff0c;從而實現對系統的完全控制。 一、漏洞詳情 這兩…

【Docker基礎】Docker鏡像管理:docker push詳解

目錄 引言 1 Docker鏡像推送基礎概念 1.1 什么是Docker鏡像推送 1.2 鏡像倉庫概述 1.3 鏡像標簽與版本控制 2 docker push命令詳解 2.1 基本語法 2.2 常用參數選項 2.3 實際命令示例 2.4 推送流程 2.5 步驟描述 3 鏡像推送實踐示例 3.1 登錄管理 3.2 標簽管理 3…

FPGA基礎 -- Verilog行為建模之循環語句

行為級建模&#xff08;Behavioral Modeling&#xff09;是 Verilog HDL 中最接近軟件編程語言的一種描述方式&#xff0c;適用于功能建模和仿真建模的初期階段。在行為級中&#xff0c;循環語句&#xff08;loop statements&#xff09;是常見且重要的控制結構&#xff0c;用于…

從C學C++(7)——static成員

從C學C(7)——static成員 若無特殊說明&#xff0c;本博客所執行的C標準均為C11. static成員和成員函數 對于特定類型的全體對象而言&#xff0c;有時候可能需要訪問一個全局的變量。比如說統計某種類型對象已創建的數量。 通常在C中使用全局變量來實現&#xff0c;如果我們…

大模型和ollama一起打包到一個docker鏡像中

如何將大模型鏡像和 Ollama 鏡像打包在一個 Docker 鏡像中 最近工作中有個需求是將ollama和大模型一起打成一個鏡像部署&#xff0c;將自己的操作步驟分享給大家。將大模型與 Ollama 服務打包在同一個 Docker 鏡像中&#xff0c;可以簡化部署流程并確保環境一致性。下面詳細介…

2025年滲透測試面試題總結-攻防研究員(應用安全)(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 攻防研究員(應用安全) 一、基礎部分 1. HTTP狀態碼對比 2. HTTP請求方法核心作用 3. 網絡分層協議速查表…

SpringBoot新聞項目學習day3--后臺權限的增刪改查以及權限管理分配

新增管理員修改管理員刪除管理員登錄 新增管理員 1.點擊新增按鈕打開一個對話框 2.確定新增對話框要顯示哪些內容 3.提交 4.后端處理、保存 5.響應前端 vue代碼 <template><!-- 新增代碼內容是比較多的,建議抽取出來,定義到一個獨立的vue文件中在列表組件中導入…

算法導論第二十五章 深度學習的倫理與社會影響

第二十五章 深度學習的倫理與社會影響 技術的光芒不應掩蓋倫理的陰影 隨著深度學習技術在各領域的廣泛應用&#xff0c;其引發的倫理和社會問題日益凸顯。本章將深入探討這些挑戰&#xff0c;并提供技術解決方案和最佳實踐&#xff0c;引導讀者構建負責任的人工智能系統。 25.…

Linux中ansible模塊補充和playbook講解

一、模塊使用 1.1 Yum模塊 功能&#xff1a;管理軟件包&#xff0c;只支持RHEL&#xff0c;CentOS&#xff0c;fedora&#xff0c;不支持Ubuntu其它版本 參數說明name要操作的軟件包名稱&#xff0c;支持通配符&#xff08;如 httpd, nginx*&#xff09;&#xff0c;也可以是…

唐代大模型:智能重構下的盛世文明圖譜

引言&#xff1a;當長安城遇見深度學習 一件唐代鎏金舞馬銜杯銀壺的虛擬復原品正通過全息投影技術演繹盛唐樂舞。這個跨越時空的場景&#xff0c;恰似唐代大模型技術的隱喻——以人工智能為紐帶&#xff0c;連接起長安城的盛世氣象與數字時代的文明重構。作為人工智能與歷史學…

國產ARM/RISCV與OpenHarmony物聯網項目(三)網關設備控制

一、設備控制界面與功能設計 程序界面運行與設計效果如下: 設備控制相關程序調用關系圖如下&#xff1a; 其中device_control.html程序為網頁界面顯示程序&#xff0c;led_alarm.cgi程序為光線數據的報警超限數據設置與管理&#xff0c;led_control.cgi程序功能為對Led燈的開…

微信小程序反編譯實戰教程

在實際滲透測試或安全分析中&#xff0c;經常會遇到微信小程序中的簽名加密&#xff08;sign&#xff09;機制&#xff0c;這些機制大多具備防重放、防篡改的特性&#xff0c;導致我們在抓包時難以直接復現請求。 &#x1f50d; 另一方面&#xff0c;一些小程序的代碼中往往會…

【NLP入門系列三】NLP文本嵌入(以Embedding和EmbeddingBag為例)

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 博主簡介&#xff1a;努力學習的22級本科生一枚 &#x1f31f;?&#xff1b;探索AI算法&#xff0c;C&#xff0c;go語言的世界&#xff1b;在迷茫中尋找光芒…

文心一言(ERNIE Bot):百度打造的知識增強大語言模型

1. 產品概述 文心一言&#xff08;ERNIE Bot&#xff09;是百度自主研發的知識增強大語言模型&#xff0c;于2023年3月16日正式發布&#xff0c;對標OpenAI的ChatGPT&#xff0c;具備文本生成、多模態交互、邏輯推理、中文理解等能力。該模型基于百度的飛槳深度學習平臺和文心…