深入 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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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)} \…