垃圾回收標記算法:三色標記

文章目錄

  • 1 三色標記流程
    • 1.1 初始標記
    • 1.2 并發標記
    • 1.3 重新標記
    • 1.4 清除階段(Sweep)
    • 1.5 為什么初始標記和重新標記需要STW,而并發標記不需要?
  • 2 并發標記的寫屏障
  • 3 多標問題
  • 4.漏標問題
    • 4.1 漏標的兩個必要條件
    • 4.2 解決方案一:增量更新(CMS)
    • 4.3 解決方案二:原始快照(SATB,G1)
    • 4.4 為什么 G1 選擇 SATB?
  • 5.面試回答模板

1 三色標記流程

三色標記算法是一種JVM中垃圾標記的算法,他可以減少JVM在GC過程中的STW時長,他是CMSG1等垃圾收集器中主要使用的標記算法

在出現三色標記算法之前,JVM中垃圾對象的標記主要采用可達性分析算法及引用計數法。但是這兩種算法存在以下問題:

  • 1、循環引用問題,如果兩個對象互相引用,就形成了一個環形結構,如果采用引用計數法的話,那么這兩個對象將永遠無法被回收。
  • 2、STW時間長,可達性分析的整個過程都需要STW,以避免對象的狀態發生改變,這就導致GC停頓時長很長大大影響應用的整體性能。

為了解決上面這些問題,就引入了三色標記法.
三色標記法將對象分為三種狀態:白色、灰色和黑色

  • 白色:該對象沒有被標記過
  • 灰色: 該對象已經被標記過了,但該對象的引用對象還沒標記完
  • 黑色: 該對象已經被標記過了,并且他的全部引用對象也都標記完了,

三色標記法的標記過程可以分為三個階段: 初始標記(Initial Marking)并發標記 (Concurrent Marking)重新標記 (Remark)

1.1 初始標記

  • 目標:標記所有GC Roots 直接引用的對象
  • 操作:
    • 所有對象初始為 白色。
    • 從 GC Roots(如虛擬機棧引用、方法區靜態屬性、本地方法棧引用等)出發,將 直接引用的對象 標記為 灰色。
    • 初始標記階段只掃描 GC Roots 的直接引用鏈,不深入遍歷整個對象圖。
  • 是否 STW:是(Stop The World)。
  • 特點:時間短,僅掃描根對象的直接引用。

1.2 并發標記

  • 目標:從灰色對象出發,遍歷整個對象圖,標記所有可達對象
  • 操作:
    • 從灰色集合中取出對象,將其標記為 黑色,并將其引用的白色對象標記為 灰色。
    • 重復上述過程,直到灰色集合為空。
    • 在此階段,應用程序線程與 GC 線程并發執行,用戶代碼可能修改對象引用關系
  • 是否 STW:否(無需 Stop The World)。
  • 關鍵問題:
    • 并發修改的挑戰:用戶線程可能新增或斷開引用,導致漏標或多標(如黑色對象新增引用白色對象)。
    • 解決方案:使用 寫屏障(Write Barrier) 技術,攔截對象引用的修改操作,并更新標記狀態。
      • 增量更新(Incremental Update):當黑色對象新增指向白色對象的引用時,記錄該引用,后續重新掃描。
      • 刪除寫屏障(Destructive Write Barrier):當白色對象的引用被斷開時,將其標記為灰色。
  • 耗時分析:
    • 最耗時的階段,需遍歷整個對象圖。
    • 優勢:通過并發執行,減少 STW 時間,提升系統響應性。

1.3 重新標記

  • 目標:修正并發標記階段中因用戶線程修改對象引用導致的漏標或誤標
  • 操作:
    • 從灰色集合重新開始遍歷對象圖,修正標記狀態。
    • 處理 未被并發標記階段遍歷到的對象(如新增的引用)。
  • 是否 STW:是(Stop The World)。
  • 特點:
    • 時間通常較短,因為只需修正少量錯誤

以上三個標記階段中,初始標記和重新標記是需要STW的,而并發標記是不需要STW的。其中最耗時的其實就是并發標記的這個階段,因為這個階段需要遍歷整個對象樹,而三色標記把這個階段做到了和應用線程并發執行,大大降低了GC的停頓時長

1.4 清除階段(Sweep)

  • 目標:回收所有 白色對象(不可達對象)。
  • 操作:
    • 遍歷堆內存,回收白色對象的內存空間。
    • 將黑色對象重置為白色,以便下次 GC 使用。
  • 是否 STW:否(部分垃圾收集器可并發執行)。

1.5 為什么初始標記和重新標記需要STW,而并發標記不需要?

在初始標記階段,針對根 (GCRoot)直接引用的對象進行標記,這個過程也通常被叫做根掃描

為了防止在初始標記過程中根對象被修改,這個過程是STW的,雖然G1可以通過采用寫屏障技術來獲知對象是否發生了修改,但是因為大多數的GCRoot他并不是對象,所以無法被獲知的,所以,這個階段是需要進行STW的。

重新標記階段,目的是修正并發標記階段因應用程序繼續運行而產生的任何變化(因為并發標記沒有STW,所以會有變化)。此時,需要重新檢查和更新那些在并發標記階段可能發生變化的對象標記信息。

重新標記是清理前的最后一次標記,需要確保這個過程的準確性,所以需要做STW來保證。

總之,三個階段,為了提升性能肯定是能不STW就不STW,而最后一個階段一一重新標記因為是最終階段,所以需要STW來確保準確性。而第一個階段一初始標記,因為無法感知到GCRoot的變化,所以需要做STW來確保這個階段的準確性。

2 并發標記的寫屏障

并發標記過程中,應用程序線程可能會修改對象圖,因此垃圾回收器需要使用寫屏障 (Write Barrier) 技術來保證并發標記的正確性

寫屏障是一種在對象引用被修改時,將其新的引用信息記錄在特殊數據結構中的機制。在三色標記法中,寫屏障技術被用于記錄對象的標記狀態,并且只對未被標記過的對象進行標記。

當應用程序線程修改了一個對象的引用時,寫屏障會記錄該對象的新標記狀態。如果該對象未被標記過,那么它會被標記為灰色,以便在垃圾回收器的下一次遍歷中進行標記。如果該對象已經被標記為可達對象,那么寫屏障不會對該對象進行任何操作。

通過使用寫屏障技術,可以使得三色標記法過程中標記更加準確。然而,盡管寫屏障對于維護垃圾收集器的準確性至關重要,它們仍然存在一些局限性,

  • 1.性能開銷.: 寫屏障會引入額外的性能開銷,因為每次對象引用更新時都需要執行額外的代碼。這種開銷可能導致系統性能下降,尤其是在高度并發的場景中
  • 2.并發修改的挑戰: 在高度并發的應用中,對象的引用可能會頻繁變化。寫屏障需要在每次引用變化時及時更新信息,但在極端并發條件下,可能難以捕捉到所有的變化。
  • 3.保守策略導致的多標: 為了避免誤刪除有效對象,一些垃圾收集器可能采取保守策略,在存在不確定性時選擇保留對象。這可能導致實際上已經不再使用的對象被錯誤地標記為存活。
  • 4.優化策略的雙刃劍: 為了減輕性能開銷,某些垃圾收集器可能采用優化策略,例如只在特定條件下激活寫屏障。這種優化有可能導致某些引用更新被錯過,影響標記的準確性。

3 多標問題

所謂多標,其實就是這個對象原本應該被回收掉的白色對象,但是被錯誤的標記成了黑色的存活對象。從而導致這個對象沒有被GC回收掉。

這個一般發生在并發標記過程中,該對象還是有引用的,但是在過程中,應用程序執行過程中把他的引用關系刪除了,導致他變成了一個垃圾對象,

多標的話,會產生浮動垃圾,這個問題一般都不太需要解決,因為這種垃圾一般都不會太多,另外在下一次GC的時候也都能被回收掉。

4.漏標問題

4.1 漏標的兩個必要條件

  • 黑色對象新增引用白色對象(條件①)
    • 黑色對象(已標記為存活)新增指向白色對象(未被標記)的引用,導致白色對象被漏標。
  • 灰色對象刪除對白色對象的引用(條件②)
    • 灰色對象(正在掃描)在掃描完成前斷開對白色對象的引用,導致白色對象失去所有路徑連接。

漏標必須同時滿足這兩個條件才會發生。因此,解決方案只需要 破壞其中一個條件 即可。

4.2 解決方案一:增量更新(CMS)

目標:破壞條件①(黑色對象新增引用白色對象)

  • 核心思想:如果黑色對象新增了對白色對象的引用,就 將黑色對象重新標記為灰色,并在后續重新掃描其引用鏈。這樣白色對象會被標記為灰色,避免漏標。
  • 具體操作:
    • 寫屏障:當黑色對象新增引用白色對象時,記錄該引用關系。
    • 重新標記階段:以這些新增的引用為起點,重新掃描黑色對象的引用鏈。
  • 類比:
    • 假設你在打掃房間(GC),已經標記某個抽屜(黑色對象)里的物品為“必須保留”。此時家人往抽屜里放了新東西(白色對象)。
    • 增量更新就像家人給你留個便條:“這個抽屜有新增物品,請重新檢查”,你就會回去重新掃描抽屜,確保新物品不被遺漏。
  • 優點:
    • 不產生浮動垃圾(所有被引用的對象都會被正確標記)。
  • 缺點:
    • 需要重新掃描整個引用鏈,耗時較長(尤其是引用鏈復雜時)

4.3 解決方案二:原始快照(SATB,G1)

目標:破壞條件②(灰色對象刪除對白色對象的引用)

  • 核心思想:在 GC 開始時,記錄所有存活對象的狀態(快照)。即使后續引用被刪除,也以快照為準,確保白色對象不會被漏標。
  • 具體操作:
    • 寫屏障:當灰色對象刪除對白色對象的引用時,記錄該白色對象為“快照中的存活對象”。
    • 重新標記階段:以這些白色對象為起點,重新掃描它們的引用鏈。

4.4 為什么 G1 選擇 SATB?

  • 性能優先:
  • SATB 只需掃描被刪除引用的對象(通過 RSet 和 Card Table 快速定位),而增量更新需要重新掃描整個引用鏈。
  • 對于大堆場景(如 G1 的 Region 劃分),SATB 的效率優勢更明顯。
  • 浮動垃圾容忍度高:
    • 浮動垃圾只是延遲到下一輪 GC 清理,不會影響當前 GC 的準確性。相比而言,增量更新的耗時可能影響系統響應時間。
  • 與 Region 結構適配:
    • G1 的 Region 結構天然支持 RSet(記錄跨 Region 引用),方便快速定位被刪除引用的對象。

5.面試回答模板

垃圾回收機制需要分為兩個步驟進行,第一標記出哪些是需要回收的垃圾,第二根據相應的清除機制如:標記復制、標記清除、標記整理等,而三色標記就是為了避免標記垃圾時STW的問題,三色標記將對象分為三種顏色,白色、灰色、黑色、其中白色表示未被引用的對象也是需要刪除的對象,灰色表示對象已經被標記,但其引用還未標記,黑色表示對象及其引用都已經被標記,整個標記過程主要分為三個階段:初始標記、并發標記和重新標記,初始標記主要是從GC Root出發,直接將引用對象標記為灰色,此時會引起stw,但耗時較短,并發標記從灰色對象出發,遍歷整個對象圖,耗時最長,但是不會引起stw,會和工作線程并發執行,但是并發執行期間會產生一些浮動的垃圾,這些浮動垃圾需要依靠重新標記去修正,此時也會引起stw,防止產生更多的浮動垃圾,并發標記階段會通過寫屏障來保證并發標記的準確性,針對漏標的問題一般可以通過增量更新或快照的方式去解決

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

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

相關文章

反射的詳解

目錄一、反射1.JDK,JRE,JVM的關系2.什么是反射3. 三種獲取Class對象(類的字節碼)的方式4.Class常用方法5. 獲取類的構造器6.反射獲取成員變量&使用7.反射獲取成員方法8.綜合例子一、反射 1.JDK,JRE,JVM的關系 三者是Java運行環境的核心組成部分,從包含關系上看…

Grafana Tempo日志跟蹤平臺

以下是Grafana Tempo文檔的總結(基于最新版文檔內容): 核心概念 分布式追蹤系統:Tempo是開源的分布式追蹤后端,專注于高吞吐量、低成本存儲和與現有監控生態的深度集成 架構組成: Distributor&#xff1a…

Qt基本控件

Qt 的基本控件是構建用戶界面的基礎,涵蓋了按鈕、輸入框、容器、顯示組件等,適用于傳統 Widget 開發(基于 QWidget)。以下是常用基本控件的分類總結:一、按鈕類控件用于觸發交互操作,如提交、取消、選擇等。…

用Voe3做AI流量視頻,條條10W+(附提示詞+白嫖方法)

最近 AI 視頻的風從大洋彼岸吹過來,Voe3 的技術升級,誕生了很多很有意思的玩法。 比如:AI ASMR 切水果解壓視頻,卡皮巴拉旅行博主、雪怪 AI Vlog,動物奧運會、第一人稱視角穿越古戰場直播。 這些視頻的流量很好&…

嵌入式學習的第四十八天-中斷+OCP原則

一、GIC通用中斷控制器 1.GIC通用中斷控制器 GIC 是 ARM 公司給 Cortex-A/R 內核提供的一個中斷控制器,GIC接收眾多外部中斷,然后對其進行處理,最終通過VFIQ、VIRQ、FIQ 和 IRQ給內核;這四個 信號的含義如下: VFIQ:虛擬…

一周學會Matplotlib3 Python 數據可視化-繪制條形圖(Bar)

鋒哥原創的Matplotlib3 Python數據可視化視頻教程: 2026版 Matplotlib3 Python 數據可視化 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 課程介紹 本課程講解利用python進行數據可視化 科研繪圖-Matplotlib,學習Matplotlib圖形參數基本設置&…

阿里研發效能提升【60篇】

阿里研發效能提升【60篇】 1、建立研發效能提升的系統框架 01、《從DevOps到BizDevOps,研發效能提升的系統方法》 視頻版:2021云棲大會云效BizDevOps論壇 文字版:深度 | 從DevOps到BizDevOps, 研發效能提升的系統方法-阿里云開發者社區 …

面試實戰 問題二十六 JDK 1.8 核心新特性詳解

JDK 1.8 核心新特性詳解 1. Lambda表達式 最核心的特性,簡化函數式編程,語法:(參數) -> 表達式 // 傳統方式 Runnable r1 new Runnable() {Overridepublic void run() {System.out.println("傳統方式");} };// Lambda方式 Runn…

STM32H743開發周記問題匯總(串口通訊集中)

溢出錯誤出現的串口接收過程中,中斷接收在溢出后無法進入,需要重點考慮溢出問題,以下是溢出恢復代碼波特率115200 優先級0-1 高于定時器 初步診斷是數據流導致的接收溢出問題/*** brief 檢查并清除UART溢出錯誤(帶狀態…

Linux中FTP配置與vsftpd服務部署指南

Linux中FTP配置與vsftpd服務部署指南 一、FTP 核心概念 1、基本定義 文件傳輸協議(FTP),基于 C/S模式 工作。控制端口:21(身份驗證與指令傳輸) 數據端口:20(主動模式數據傳輸&#x…

Web UI自動化測試的早期介入?

在傳統研發流程中,Web UI自動化測試常被視為“后期活動”——必須等待前端界面完全穩定才能啟動。這種滯后導致自動化測試難以覆蓋早期迭代,形成“開發等測試、測試等穩定”的惡性循環。本文將系統破解這一困局,提供一套從需求階段介入、持續…

基于學科競賽的高職計算機網絡教學解決方案

一、引言《關于深化產教融合的若干意見》明確提出 “推行面向企業真實生產環境的任務培養模式”,為我國職業教育發展指明了產教深度融合的方向。在數字經濟時代,計算機網絡技術正以前所未有的速度迭代更新,產業界對具備前沿技術應用能力和實踐…

猿大師中間件:Chrome網頁內嵌PhotoShop微信桌面應用程序

隨著桌面應用程序集成到網頁的需求不斷增長,尤其在Chrome瀏覽器缺乏原生調用EXE功能的情況下,傳統網頁內嵌解決方案面臨失效挑戰,猿大師中間件因此發展成為當前主流方案。 2025年猿大師發布了EXE、OCX、COM三個通用組件,自此猿大…

EF (Entity Framework) vs LINQ to SQL vs SqlSugar 全方位對比分析

文章目錄1. 概述與背景介紹1.1 Entity Framework (EF)1.2 LINQ to SQL1.3 SqlSugar2. 架構設計對比2.1 EF架構設計2.2 LINQ to SQL架構2.3 SqlSugar架構3. 性能對比3.1 基準測試數據3.2 性能分析3.3 內存使用4. 功能特性對比4.1 數據庫支持4.2 主要功能對比4.3 高級特性5. 開發…

MySQL 多表聯查與內外連接詳解

多表聯查是關系型數據庫的核心操作,用于從多個表中關聯數據。MySQL 支持多種連接方式,最常用的是內連接和外連接(左/右/全外連接)。一、多表聯查基礎語法 SELECT 列列表 FROM 表1 [連接類型] JOIN 表2 ON 連接條件 [連接類型] JOI…

《網絡爬蟲》

網絡爬蟲,是一種自動化程序,用于抓取互聯網上的數據。它們通過模擬瀏覽器行為,抓取網頁內容并提取有用信息。爬蟲廣泛應用于數據采集、搜索引擎索引、競爭對手分析等領域。爬蟲的工作流程:請求目標網頁:爬蟲首先發送 H…

openpnp - 頂部相機環形燈光DIY

文章目錄openpnp - 頂部相機環形燈光DIY概述筆記ENDopenpnp - 頂部相機環形燈光DIY 概述 底部相機燈光用環形燈(用鈑金折彎成一個10mm高的矩形盒子)是可以的。因為吸嘴落到Z方向和PCB平齊時,用COB燈帶裝在一個矩形盒子中正好能照射到吸嘴尖端高度附近。 頂部相機…

[AI React Web] E2B沙箱 | WebGPU | 組件樹 | 智能重構 | 架構異味檢測

第三章:E2B沙箱交互 在前兩章中,我們掌握了對話狀態管理和AI代碼生成管道的運作原理。 但生成代碼如何真正運行?這正是E2B沙箱交互的核心價值。 架構定位 E2B沙箱是專為open-lovable打造的虛擬計算環境,具備以下核心能力&…

Redis寶典

Redis是什么 Redis是開源的,使用C語言編寫的,支持網絡交互,可基于內存也可持久化到本地磁盤的Key-Value數據庫。 優點: 因為Redis是基于內存的,所以數據的讀取速度很快Redis支持多種數據結構,包括字符串Str…

MyBatis-Plus 分頁失效問題解析:@Param 注解的影響與解決方案

引言在 Spring Boot MyBatis-Plus 的開發中,分頁查詢是常見的需求。然而,有時我們會遇到分頁失效的問題,尤其是在方法參數上添加 Param 注解后。本文將通過一個實際案例,分析 Param 注解如何影響 MyBatis-Plus 的分頁機制&#x…