Go 语言的 GC 垃圾回收

article/2025/8/24 9:23:12

序言

 垃圾回收(Garbage Collection,简称 GC)机制 是一种自动内存管理技术,主要用于在程序运行时自动识别并释放不再使用的内存空间,防止内存泄漏和不必要的资源浪费。这篇文章让我们来看一下 Go 语言的垃圾回收机制是如何设计的吧。


一、为什么需要垃圾回收?

 熟悉 C/C++ 编程的同学肯定清楚自己手动管理内存的手段:

  • 分配内存:malloc, new
  • 释放内存:free, delete

对待内存管理一定要小心谨慎,不然稍有疏漏就会引起以下严重的问题:

  • 忘记释放内存 → 内存泄漏
  • 多次释放同一块内存 → 崩溃或未定义行为
  • 访问已释放的内存 → 悬空指针

所以说垃圾回收机制大大的提高了内存管理的下限,但是同时这是以一定的性能开销换取的。


二、Go 垃圾回收机制

 我们现在看到的机制都是比较完善的,但是很多时候我们不明白他为什么要这么做,有什么好处?这是因为我们站在巨人的肩膀上,机制是在使用中不断完善的。所以看事情不能只看现在,明白他大致来时候的路是必要的。

2.1 标记-清扫式垃圾回收(Mark-Sweep GC)

2.1.1 回收流程

 首先当前执行的逻辑暂停(也称为 Stop-The-World STW),然后标记所有存活对象。从根对象(比如全局变量、当前栈中的局部变量等)开始遍历所有被引用的对象,并将对象标记为存活状态:
在这里插入图片描述
现在标记的动作完成了,需要回收没有被引用的空间了。遍历整个堆的空间,然后对于没有被标记的对象,释放其内存:
在这里插入图片描述
最后便是恢复程序的执行了,可以看出刚开始的机制还是比较简单的。

2.1.2 Mark-Sweep 的缺点

STW 时间长降低了程序的执行的效率。如果当前的程序对于空间的申请和释放的操作比较频繁时,执行时的卡顿感会愈发的强烈,因为 STW 这段时间程序是被阻塞的,无法正常运行。
 内存碎片化严重。清扫后会产生很多小块的空闲内存,可能导致大对象无法分配,降低了内存的利用率。
 扫描整个堆。如果当前堆比较大的话,也会拉长 STW 的时间。

这个方式是在 Go V1.4 之前使用的,现在被替换了,但是作为一个引子还是不错的。

2.2 三色并发垃圾回收(Tri-color Concurrent GC )

2.2.1 回收流程

 首先在每次创建新的对象的时候将该对象标记为 白色
在这里插入图片描述
现在触发 GC 了,从根节点遍历,将该节点 root 指向的堆对象从 white 表 放入 grey 表,由于这里只有一个根对象,所以这里只需要处理 a
在这里插入图片描述
根上的对象遍历完成了,现在遍历 grey 表 将节点 a 指向的对象也全放入 grey 表 ,同时将 a 放入 black 表 表示他的可达对象处理完成了:在这里插入图片描述
之后重复第二部操作直至 grey 表 的数据为空:
在这里插入图片描述
到最后我们发现 white 表 只剩下了一个不可达对象 f,这个就是需要回收的空间。纵观整个过程,其实就是一个广度遍历来查找不可达对象的过程。
 比较现有的两个机制,后者一个很大优点就是 不需要遍历整个堆来查找不可达对象,因为最开始的时候就记录了创建的每一个对象。但是我们这里好像少了些什么,不需要 STW 吗?

2.2.2 假设没有 STW

 就比如 e 其实是一个可达对象的,但是由于在执行回收的过程中当前的程序也在正常的执行,让 de 断开连接并让一个新的根节点(比如局部变量)指向 e
在这里插入图片描述
因为对根节点的遍历只在最初执行一遍,后续不会再遍历了导致错误地判定 e 为不可达对象释放该空间,这不就错误地释放空间了吗(也称为 漏标)。
 最直接的方式就是在回收的过程中加上 STW,但是这个方式的弊端上面也说过了。那怎么办呢?减少 STW 的时间。

2.2.3 屏障机制
1. 强弱三色不变式

 由于程序的执行和垃圾回收的过程是并发的,就导致了错误地回收了某些还需要继续使用的对象。为了避免这种情况,引入了 三色不变式
强三色不变式,所有黑对象不能直接或间接引用白对象。也就是说:如果一个对象已经是黑色,它不能指向任何未被标记的白色对象。
弱色不变式。所有白对象可以被黑色对象引用,但是这个白色对象必须存在着其他灰色对象对他的引用。

2. 插入写屏障

满足:强三色不变式
操作:当一个黑色对象引用一个白色对象之前,先将该白色对象修改为灰色对象,在建立引用:
在这里插入图片描述
并且这里还有一个机制是 插入写屏障只作用于堆对象。因为栈上的变量变更比较频繁, 如果一变更我们就去执行插入写屏障会非常的耽误时间。作为补偿,会在整体三色标记清除之后,专门对栈上的空间执行次三色标记扫描并加上 STW 保护。

3. 删除写屏障

满足:弱三色不变式
操作:当一个白色对象被上游删除引用时,会将将自己修改为灰色对象:
在这里插入图片描述
这种方式其实也是延迟回收策略,当真正想删除该对象时,这一轮他会存活下来,但是下一轮肯定会被带走。

2.3.4 Tri-color Concurrent 的缺点

 这两种方式任选一种即可解决漏标的问题,Go V1.8 及以前使用的是删除写屏障。该种方式的缺点是:

  • 回收精度偏低。本次 GC 过程中需要删除的对象会在下一轮清除

而插入写屏障的缺点也不小:

  • 会在结束时扫描整个栈,并且伴随着 STW

那是否可以取长补短互相融合呢?

2.3 混合写屏障机制(Hybrid Write Barrier)

 将栈上的对象扫描之后全部标记为 黑色,期间任何新增的对象标记为 灰色,任何被删除的对象也标记为 灰色。这样节省了扫描整个栈并伴随的 STW 带来的性能消耗。


三、总结

 现在纵观大体的发展路线,你是否可以理解:混合写屏障(Hybrid Write Barrier)是一种改进型写屏障机制,它结合了 删除写屏障 和 插入写屏障 的优点,在并发三色标记中有效地防止漏标问题,并显著减少了 STW 时间。


http://www.hkcw.cn/article/rOrpbkWgbN.shtml

相关文章

qwen 2.5 并行计算机制:依靠 PyTorch 和 Transformers 库的分布式能力

qwen 2.5 并行计算机制:依靠 PyTorch 和 Transformers 库的分布式能力 完整可运行代码: import torch import torch.nn.functional as F from transformers

如何评估CAN总线信号质量

CAN总线网络的性能在很大程度上取决于其信号质量。信号质量差可能导致通信错误,进而引发系统故障、效率降低甚至安全隐患。因此,评估和确保CAN总线信号质量是维护系统健康和可靠性的关键。 在CAN总线网络中,数据通过双绞线上的差分信号传输。…

第三方软件评测机构如何助力软件品质提升及企业发展?

第三方软件评测机构与软件开发者及使用者无直接关联,它们提供全方位的检测和公正的评价服务。这样的评测可以展现客观的成效,对提升软件的品质具有显著影响,且在软件产业中发挥着至关重要的角色。 评测的客观性 独立第三方机构与软件开发者…

Linux之MySQL安装篇

1.确保Yum环境是否能正常使用 使用yum环境进行软件的安装 yum -y install mysql-server mysql2.确保软件包已正常完成安装 3.设置防火墙和selinux配置 ## 关闭防火墙 systemctl stop firewalld## 修该selinux配置 vim /etc/selinux/config 将seliuxenforcing修改为sel…

Java 项目架构设计:模块化、分层架构的实战经验

Java 项目架构设计:模块化、分层架构的实战经验 在当今复杂多变的软件开发领域,Java 项目架构设计起着至关重要的作用。良好的架构设计不仅能够提升项目的可维护性、可扩展性,还能有效降低系统的耦合度,提高开发效率。而模块化与…

uniapp 键盘顶起页面问题

关于uniapp中键盘顶起页面的问题。这是一个在移动应用开发中常见的问题,特别是当输入框位于页面底部时,键盘弹出会顶起整个页面,导致页面布局错乱。 pages.json 文件内,在需要处理软键盘的页面添加 softinputMode 配置&#xff1…

截面动量策略思路

该策略旨在实现期货日频多品种交易,采用MA双均线结合百分比追踪止损的方法。策略建议初始资金为1000000元,并基于2012年1月1日至今的数据进行回测。策略的核心逻辑包括主力合约的动态切换、双均线交叉信号的生成以及基于百分比的追踪止损机制。 交易逻辑…

HCIE-STP复习

文章目录 STP STP 🏡作者主页:点击! 🤖Datacom专栏:点击! ⏰️创作时间:2025年05月31日13点17STP通过三要素选举消除环路: 根桥(BID最小,建议设优先级为0&…

Git入门到精通:30分钟掌握核心技巧

目录 一、基础理论片 Git简介 Git安装 Git仓库 Git基本命令用法 仓库别名 二、实操命令篇 远程分支 分支的新建和合并 实操演示 1 本地新建仓库 2 gitee新建仓库 3 建立关系 4 新建分支 5 开发新功能 6 推送新分支 7 合并新分支到主分支 三、可视化工具篇 G…

告别压降损耗与反向电流困扰:汽车电子电源防反接方案全面解析与理想二极管应用

在汽车电子系统中,由于电源反接、快速负脉冲群、微关断、叠加交流等防护要求,需要设计防反电路。常见电路中,依赖肖特基二极管实现电池反接保护和电源冗余(ORing)设计。然而,随着功率密度和效率要求飙升&am…

5.1 初探大数据流式处理

在本节中,我们深入探讨了大数据流式处理的基础知识和关键技术。首先,我们区分了批式处理和流式处理两种大数据处理方式,了解了它们各自的适用场景和特点。流式处理以其低延迟和高实时性适用于需要快速响应的场景,而批式处理则适用…

线程概念与控制

目录 Linux线程概念 什么是线程 分页式存储管理 虚拟地址和页表的由来 物理内存管理 页表 提问 解答 缺页异常 线程的优点 线程的缺点 线程异常 Linux进程VS线程 进程与线程 进程的多个线程共享 进程与线程关系如图 Linux线程控制 POSIX线程库 创建线程 测试…

SAR ADC 同步逻辑设计

SAR ADC的逻辑是重要的一个模块,可以分为同步逻辑和异步逻辑,对于低速SAR ADC,一般采用同步逻辑,对于高速SAR ADC,一般采用异步逻辑。 对于同步逻辑,由于架构不同,有先置位再比较,也…

用不太严谨的文字介绍遥测自跟踪天线的基本原理

前两天跟一个客户见面的时候,客户问我:遥测自跟踪天线能够跟踪目标,是什么原理?不需要目标的位置,怎么做到自跟踪的? 突然一瞬间,有点语塞。 难道要介绍天线、馈源、极化、左旋、右旋、和差网…

谷歌工作自动化——仙盟大衍灵机——仙盟创梦IDE

下载地址 https://chromewebstore.google.com/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd https://chrome.zzzmh.cn/info/mooikfkahbdckldjjndioackbalphokd

AI学习笔记(一)背景学习

什么是AI、机器学习、深度学习、强化学习,他们之间是什么关联关系? AI(Artificial_intelligence):即人工智能是指计算系统执行通常与人类智能相关的任务的能力,例如学习、推理、解决问题、感知和决策 机器…

2000-2023年 上市公司-气候风险总词频、气候风险指数-社科经管实证数据

2000-2023年上市公司-气候风险总词频、气候风险指数-社科经管https://download.csdn.net/download/paofuluolijiang/90880454 https://download.csdn.net/download/paofuluolijiang/90880454 本数据集涵盖2000至2023年中国A股上市公司的气候风险相关文本信息及量化指标&#x…

Vue-自定义指令

自定义指令 简单写法 v-twoAge 功能&#xff1a; 当前年龄翻倍 注意&#xff1a;指令方法名称 小写 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>自定义指令</title><!-- 引入V…

力扣HOT100之动态规划:152. 乘积最大子数组

这道题并不是代码随想录里的&#xff0c;我试着用动规五部曲来做&#xff0c;然后不能通过全部测试样例&#xff0c;在第109个测试样例卡住了&#xff0c;如下所示。 原因是可能负数乘以负数会得到最大的乘积&#xff0c;不能单纯地用上一个序列的最大值乘以当前值来判断是否能…

应急响应靶机-web2-知攻善防实验室

题目&#xff1a; 前景需要&#xff1a;小李在某单位驻场值守&#xff0c;深夜12点&#xff0c;甲方已经回家了&#xff0c;小李刚偷偷摸鱼后&#xff0c;发现安全设备有告警&#xff0c;于是立刻停掉了机器开始排查。 这是他的服务器系统&#xff0c;请你找出以下内容&#…