深入 Go 底層原理(六):垃圾回收(GC)

1. 引言

Go 語言自帶垃圾回收(Garbage Collection, GC),讓開發者從手動管理內存的繁重任務中解脫出來。Go 的 GC 以其低延遲并發性而聞名,其目標是在不長時間暫停(Stop The World, STW)整個程序的情況下完成大部分回收工作。

本文將深入探討 Go GC 的核心算法——并發三色標記清除法,以及其關鍵技術——寫屏障(Write Barrier)。

2. GC 的目標與挑戰
  • 目標:回收堆上不再被使用的對象(垃圾),并將內存返還給分配器。

  • 挑戰:如何在不影響程序正常運行(即低 STW 時間)的前提下,準確、高效地完成回收?這需要在“mutator”(用戶 Goroutine,會修改對象引用關系)和“collector”(GC Goroutine)之間進行精妙的協調。

3. 核心算法:并發三色標記-清除 (Tri-color Mark-and-Sweep)

Go GC 采用的是三色標記清除算法,它將堆上的對象分為三種顏色:

  • 白色 (White):對象的初始狀態,代表可能是垃圾。在 GC 周期結束時,所有仍然是白色的對象都將被回收。

  • 灰色 (Grey):對象本身已被標記為存活,但其引用的其他對象(其子對象)還沒有被掃描。灰色對象是待處理任務的集合。

  • 黑色 (Black):對象本身和其引用的所有子對象都已被掃描,是確認的存活對象。

GC 流程分為四個主要階段

  1. Mark Setup (STW):

    • 這是一個短暫的 STW 階段(通常在微秒級別)。

    • 主要任務是開啟寫屏障 (Write Barrier),并準備標記工作。

    • 將所有全局變量和每個 Goroutine 棧上的對象(根對象)放入灰色集合。

  2. Marking (Concurrent):

    • 這是 GC 的主要工作階段,與用戶 Goroutine 并發執行

    • GC Goroutine 會從灰色集合中取出一個對象,將其標記為黑色

    • 然后掃描該對象的所有指針字段,將其引用的所有白色對象標記為灰色,并放入灰色集合。

    • 這個過程會一直持續,直到灰色集合為空。

  3. Mark Termination (STW):

    • 這是另一個短暫的 STW 階段。

    • 主要任務是處理一些在并發標記階段中被寫屏障捕獲的、可能被遺漏的指針修改,并關閉寫屏障。

  4. Sweeping (Concurrent):

    • 此階段也與用戶 Goroutine 并發執行

    • GC 會遍歷堆中的所有 mspan,回收所有仍然是白色對象的內存塊,并將其返還給內存分配器。

4. 關鍵技術:寫屏障 (Write Barrier)

在并發標記階段,如果用戶 Goroutine(mutator)修改了對象的引用關系,可能會破壞三色標記的不變性,導致本應存活的對象被錯誤回收。

危險場景:一個黑色對象引用了一個白色對象,同時該白色對象的所有其他灰色父引用被移除了。如果不加干預,這個白色對象將永遠不會被掃描,最終被當成垃圾回收。

黑色對象 -> 白色對象

為了防止這種情況,Go 引入了寫屏障。寫屏障是編譯器插入的一小段代碼,它會“攔截”所有在堆上的指針寫操作。

混合寫屏障 (Hybrid Write Barrier, Go 1.8+): Go 的混合寫屏障結合了兩種屏障的優點,其核心思想是:

  • 它保護的是白色對象:不允許黑色對象直接引用白色對象。

  • 工作機制:當 *slot = ptr(一個指針寫操作)發生時,如果 ptr 指向一個白色對象,寫屏障會ptr 指向的對象涂成灰色

通過這種方式,任何可能被黑色對象引用的白色對象都會被“拯救”回來,加入灰色集合,從而保證了 GC 的正確性。

5. GC 的觸發時機

GC 主要由以下條件觸發:

  1. 內存分配閾值 (GOGC): 當自上次 GC 以來新分配的內存達到一個閾值時,會自動觸發新的 GC。這個閾值由環境變量 GOGC 控制(默認為 100),表示當堆大小增長 100% 時觸發。

  2. 定時觸發: runtime.sysmon 線程會定期檢查,如果距離上次 GC 超過一定時間(默認為 2 分鐘),會強制觸發一次 GC。

  3. 手動觸發: 開發者可以調用 runtime.GC() 來手動觸發一次 GC。

6. 總結

Go GC 是一個低延遲、高并發的垃圾回收系統。它通過三色標記清除算法實現了大部分工作的并發執行,通過短暫的 STW 完成必要的同步,并通過混合寫屏障技術保證了在用戶 Goroutine 并發修改對象引用時的正確性。這一系列精巧的設計,是 Go 能夠勝任高并發、低延遲服務場景的重要保障。

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

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

相關文章

專網內網IP攻擊防御:從應急響應到架構加固

內網IP攻擊防御:從應急響應到架構加固內網IP攻擊的隱蔽性遠超外網威脅,其本質是信任邊界內的權限濫用。應對需遵循"識別-隔離-溯源-加固"四步法則,兼顧應急止損與長效防御。應急處置:30分鐘響應窗口1. 流量阻斷&#xf…

Git、Gitee、GitHub、GitLab完整講解:從基礎到進階

第一部分:Git是什么? 📚比喻:Git就像是一本"時光日記本" ? 每一段代碼的改動,Git都會幫你記錄下來,像是在寫日記。 ? 如果出現問題或者想查看之前的版本,Git可以帶你"穿越回…

WinForm之CheckBox 控件

CheckBox(復選框)是 WinForm 中用于實現 “多項選擇” 的控件,允許用戶從一組選項中選擇任意數量的項(包括零項、一項或多項),適用于需要同時選擇多個選項的場景(如愛好、權限設置、功能開關等&…

鯨魚優化算法(Whale Optimization Algorithm, WOA)是一種受座頭鯨捕食行為啟發的群體智能優化算法,由Seyedali Mirjalili于2016年提出

鯨魚優化算法(Whale Optimization Algorithm, WOA)是一種受座頭鯨捕食行為啟發的群體智能優化算法,由Seyedali Mirjalili于2016年提出。 它通過模擬鯨魚的狩獵策略(特別是“氣泡網捕食”行為)來解決優化問題,廣泛應用于函數優化、工程設計、機器學習參數優化等領域。以下…

信息量,驚奇度,熵、KL散度(相對熵),交叉熵、最大似然估計MLE與最小化交叉熵的等價證明、

一: 一些基本概念 1.1 信息量:特定事件所攜帶的信息多少信息量衡量的是特定事件所攜帶的信息多少,其數學定義為:其中p(x)是事件x發生的概率。核心思想:越罕見的事件,其攜帶的信息量越大;越常見的事件&#…

VBA 64位API聲明語句第012講

跟我學VBA,我這里專注VBA, 授人以漁。我98年開始,從源碼接觸VBA已經20余年了,隨著年齡的增長,越來越覺得有必要把這項技能傳遞給需要這項技術的職場人員。希望職場和數據打交道的朋友,都來學習VBA,利用VBA,起碼可以提高…

深入理解Java中String.intern()方法:從原理到并發控制實踐

深入理解 Java 中 String.intern () 方法:從原理到并發控制實踐 在 Java 開發中,String.intern()方法是一個看似簡單卻蘊含深意的 API。它在字符串常量池管理、內存優化以及并發控制等場景中有著關鍵作用。本文將從底層原理出發,結合實際案例…

在Linux中創建LVGL應用

在Linux中創建LVGL應用 簡介 上一篇文章介紹了在imx6上開發UI的流程 . 這篇接上文, 介紹具體的開發步驟。 1. 創建項目主目錄 mkdir my_lvgl_project cd my_lvgl_project2. 初始化 Git 倉庫 (可選但推薦) git init echo "# My Project with Dependencies&…

大模型對比評測:Qwen2.5 VS Gemini 2.0誰更能打?

一、背景與選型關鍵 在 AI 應用落地的時代,“AI大模型選型對比”成為關鍵環節。選擇合適的模型要綜合考量性能、上下文長度、推理能力、中文/編程支持、成本等多維度指標。 本文重點比較 Gemini2.0Flash-Lite (Preview)、Gemini2.0Flash &a…

轉置卷積解釋與示例計算

文章目錄轉置卷積的三種等價實現方法:原理、公式與等價性分析數學定義與核心公式方法一:零填充翻轉核卷積(數學定義方法)原理與公式等價性說明方法二:直接位置映射(pytorch框架高效實現)原理與公…

關于車位引導及汽車乘梯解決方案的專業性、系統性、可落地性強的綜合設計方案與技術實現說明,旨在為現代智慧停車樓提供高效、安全、智能的停車體驗。

一、系統概述隨著城市土地資源日益緊張,立體停車、自動化停車成為發展趨勢。本方案圍繞“車位引導系統 汽車乘梯系統”構建智慧停車核心體系,結合地磁/視頻/超聲波檢測、AI識別、語音交互、電梯自動調度等先進技術,實現車輛入場、引導、停泊…

【相機】曝光時間長-->拖影

曝光時間長 → 運動目標在快門開啟期間持續移動 → 同一像素記錄多個位置的能量 → 圖像出現“拖影”(運動模糊)。🔍 具體原因卷簾快門(Rolling Shutter)效應 RealSense 的 RGB 傳感器(如 IMX 系列&#xf…

day36 力扣1049.最后一塊石頭的重量II 力扣494.目標和 力扣474.一和零

最后一塊石頭的重量II有一堆石頭&#xff0c;用整數數組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。每一回合&#xff0c;從中選出任意兩塊石頭&#xff0c;然后將它們一起粉碎。假設石頭的重量分別為 x 和 y&#xff0c;且 x < y。那么粉碎的可能結果如下&#…

Java內存模型(Java Memory Model,JMM)

?? JMM?? 是Java虛擬機&#xff08;JVM&#xff09;規范中定義的一組規則和規范&#xff0c;用于描述多線程環境下&#xff0c;Java程序中變量的訪問和修改行為&#xff0c;尤其是在并發編程中如何保證內存可見性、原子性和有序性。JMM 是 Java 并發編程的基石&…

【swoole Windows 開發(swoole-cli 開發 hyperf)】

先前swoole在Windows平臺的開發體驗極差&#xff0c;如果在Windows開發swoole的東西可以用docker或者虛擬機&#xff0c;遠程開發&#xff0c;體驗比較好的是直接Mac或者Linux系統開發。但是作為window平臺的釘子戶表示我窮。swoole之前已經推出了cygwin64編譯成winwods版本的方…

興達餐飲 酒店 進銷存管理系統軟件

興達餐飲 酒店 進銷存管理系統軟件

Seal Report:一款免費開源的報表工具

Seal Report 是一款基于 C# 語言開發的開源報表工具&#xff0c;可以從各種數據庫或 NoSQL 數據源中生成日常報告&#xff0c;并且執行復雜的計劃任務。 功能特性 免費開源&#xff1a;源代碼托管在 GitHub 上&#xff0c;用戶可以自由使用、修改、甚至集成到自己的系統中&…

WebRTC 多媒體 SDP 示例與解析

webRTC中的SDP的Bundlle可能包含一個或者多個媒體塊&#xff08;媒體描述, 源碼對應類ContentInfo&#xff09;&#xff0c;從 m 開始到下一個 m 行&#xff08;或 SDP 結束&#xff09;之間的所有屬性&#xff08;包括 a&#xff09;都屬于同一個媒體塊&#xff08;media sect…

SpringBoot 啟動富文本文字更改

正常來說 SpringBoot啟動時候&#xff0c;展示的文字是這個 、 主播這邊想要換一個樣式&#xff0c;換一個自己自定義的文字 這邊換成了自己的博客名字 具體實現操作如下 在項目目錄 resources下創建一個名字為banner.txt的文本&#xff0c;這是SpringBoot啟動的時候尋找的…

基于結構熵權-云模型的鑄鐵浴缸生產工藝安全評價

一、評價模型核心思想 結構熵權法 解決傳統熵權法忽略指標間結構關系的問題,通過指標層次網絡計算權重。 步驟: 構建工藝安全評價指標體系(樹狀/網絡結構) 計算同級指標間的影響度矩陣 引入修正熵權:wj=1?Ej∑(1?Ek)結構影響因子w_j = \frac{1 - E_j}{\sum (1 - E_k)} \…