当前位置: 首页 > article >正文

Go 语言的 GC 垃圾回收

序言

 垃圾回收(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 时间。

相关文章:

Go 语言的 GC 垃圾回收

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

[git每日一句]your branch is behind ‘origin/master‘

当 Git 提示 "your branch is behind origin/master" 时,意思是: 你的本地分支落后于远程仓库(origin)的 master 分支 即:远程仓库有新的提交,而你的本地分支尚未同步这些更新。 如何解决&…...

【QT】在QT6中读取文件的方法

在QT6中读取文件的方法 QT6提供了多种读取文件的方式&#xff0c;下面我将介绍几种常用的方法&#xff0c;包括处理文本文件和二进制文件。 1. 使用QFile和QTextStream读取文本文件 这是读取文本文件最常用的方法&#xff1a; #include <QFile> #include <QTextSt…...

安全帽目标检测

安全帽数据集 这里我们使用的安全帽数据集是HelmentDetection&#xff0c;这是一个公开数据集&#xff0c;里面包含5000张voc标注格式的图像&#xff0c;分为三个类别&#xff0c;分别是 0: head 1: helmet 2: person 安全帽数据集下载地址、 我们将数据集下载后&#xff0c…...

Java工厂方法模式详解

工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种创建型设计模式&#xff0c;它将对象的创建和使用分离&#xff0c;通过定义一个创建对象的接口&#xff0c;让子类决定实例化哪个类。这种模式提高了代码的可扩展性和可维护性&#xff0c;尤其适用于需要根据…...

【pytorch学习】土堆pytorch学习笔记2

说明 主要以https://www.morinha.cc/posts/courses/pytorch-%E5%B0%8F%E5%9C%9F%E5%A0%86的内容为基础&#xff0c;没有的或者自己不是很清楚的再补充上内容&#xff0c;该贴有的内容大部分不再加入进来 新增的更全的参考&#xff1a; https://2048.csdn.net/6801fc28e9858151…...

Eclipse 插件开发 5.3 编辑器 监听输入

Eclipse 插件开发 5.3 编辑器监 听输入 1 插件配置2 添加监听3 查看效果 Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Click1 Bundle-SymbolicName: com.xu.click1;singleton:true Bundle-Version: 1.0.0 Bundle-Activator: com.xu.click1.Activator Bundle…...

iOS 集成网易云信IM

云信官方文档在这 看官方文档的时候&#xff0c;版本选择最新的V10。 1、CocoPods集成 pod NIMSDK_LITE 2、AppDelegate.m添加头文件 #import <NIMSDK/NIMSDK.h> 3、初始化 NIMSDKOption *mrnn_option [NIMSDKOption optionWithAppKey:"6f6568e354026d2d658a…...

Parasoft C++Test软件单元测试_实例讲解(对多次调用的函数打桩)

系列文章目录 Parasoft C++Test软件静态分析:操作指南(编码规范、质量度量)、常见问题及处理 Parasoft C++Test软件单元测试:操作指南、实例讲解、常见问题及处理 Parasoft C++Test软件集成测试:操作指南、实例讲解、常见问题及处理 进阶扩展:自动生成静态分析文档、自动…...

azure web app创建分步指南系列之二

为注册表授权托管标识 你创建的托管标识尚未获得从容器注册表中提取数据的授权。在此步骤中,你将启用授权。 返回容器注册表的管理页面: 在左侧导航菜单中,选择“访问控制 (IAM)”。选择“添加角色分配”。此屏幕截图显示了如何为容器注册表启用添加角色分配。在角色列表中…...

题海拾贝:P8598 [蓝桥杯 2013 省 AB] 错误票据

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…...

MySQL 8.0:解析

引言 MySQL 8.0 作为里程碑版本&#xff0c;在功能、性能、安全性等维度进行了全面革新。以下从技术实现、应用场景和实践挑战三个层面&#xff0c;深度解析其核心特性变化&#xff1a; 一、架构级重构&#xff1a;数据字典与原子 DDL 1. 事务性数据字典 技术实现…...

Python量化交易12——Tushare全面获取各种经济金融数据

两年前写过Tushare的简单使用&#xff1a; Python量化交易08——利用Tushare获取日K数据_skshare- 现在更新一下吧&#xff0c;这两年用过不少的金融数据库&#xff0c;akshare&#xff0c;baostock&#xff0c;雅虎的&#xff0c;pd自带的......发现还是Tushare最稳定最好用&…...

封装一个小程序选择器(可多选、单选、搜索)

组件 <template><view class"popup" v-show"show"><view class"bg" tap"cancelMultiple"></view><view class"selectMultiple"><view class"multipleBody"><view class&…...

Dest建筑能耗模拟仿真功能简介

Dest建筑能耗模拟仿真功能简介 全球建筑能耗占终端能源消费的30%以上&#xff0c;掌握建筑能耗模拟是参与绿色建筑认证&#xff08;如LEED、WELL&#xff09;、超低能耗设计、既有建筑节能改造的必备能力。DEST作为国内主流建筑能耗模拟工具&#xff0c;广泛应用于设计院、咨询…...

【Hot 100】121. 买卖股票的最佳时机

目录 引言买卖股票的最佳时机我的解题 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;【Hot 100】121. 买卖股票的最佳时机❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难&#xff01; 引…...

【机器学习基础】机器学习入门核心算法:XGBoost 和 LightGBM

机器学习入门核心算法&#xff1a;XGBoost 和 LightGBM 一、算法逻辑XGBoost (eXtreme Gradient Boosting)LightGBM (Light Gradient Boosting Machine) 二、算法原理与数学推导目标函数&#xff08;二者通用&#xff09;二阶泰勒展开&#xff1a;XGBoost 分裂点增益计算&#…...

Linux | Shell脚本的常用命令

一. 常用字符处理命令 1.1 连续打印字符seq seq打印数字&#xff1b;且只能正向打印&#xff0c;不可反向连续打印 设置打印步长 指定打印格式 1.2 反向打印字符tac cat 正向&#xff0c;tac 反向 1.3 打印字符printf printf "打印的内容"指定格式打印内容 换行…...

跑步的强度等级分类

概述 最大心率简化计算公式是【220-年龄】&#xff0c;具体值建议通过实际测试校准。在跑步训练中&#xff0c;以最大心率&#xff08;Heart Rate Maximum&#xff09;为指标对强度分类&#xff0c;常见分类对应的心率区间如下&#xff1a; 强度等级心率区间&#xff08;% HR…...

【JUC】深入解析 JUC 并发编程:单例模式、懒汉模式、饿汉模式、及懒汉模式线程安全问题解析和使用 volatile 解决内存可见性问题与指令重排序问题

单例模式 单例模式确保某个类在程序中只有一个实例&#xff0c;避免多次创建实例&#xff08;禁止多次使用new&#xff09;。 要实现这一点&#xff0c;关键在于将类的所有构造方法声明为private。 这样&#xff0c;在类外部无法直接访问构造方法&#xff0c;new操作会在编译…...

2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷3:共计6题带解析)

2025年全国青少年信息素养大赛复赛C++算法创意实践挑战赛真题模拟强化训练(试卷3:共计6题带解析) 第1题:四位数密码 【题目描述】 情报员使用4位数字来传递信息,同时为了防止信息泄露,需要将数字进行加密。数据加密的规则是: 每个数字都进行如下处理:该数字加上5之后除…...

Mongodb | 基于Springboot开发综合社交网络应用的项目案例(中英)

目录 Project background Development time Project questions Create Project create springboot project project framework create folder Create Models user post Comment Like Message Serive tier user login and register Dynamic Publishing and Bro…...

飞腾D2000与FPGA结合的主板

UD VPX-404是基于高速模拟/数字采集回放、FPGA信号实时处理、CPU主控、高速SSD实时存储架构开发的一款高度集成的信号处理组合模块&#xff0c;采用6U VPX架构&#xff0c;模块装上外壳即为独立整机&#xff0c;方便用户二次开发。 UD VPX-404模块的国产率可达到100%&#xff0…...

百度量子蜘蛛3.0横空出世,搜索引擎迎来“量子跃迁“级革命

一、量子蜘蛛3.0的三大颠覆性升级 1. 动态抓取&#xff1a;让内容实时"量子纠缠" - 智能频率调节&#xff1a;根据网站更新频率自动调整抓取节奏&#xff0c;新闻类站点日抓取量达3-5次&#xff0c;静态页面抓取间隔延长至72小时。某财经媒体通过"热点事件15分钟…...

GitHub开源|AI顶会论文中文翻译PDF合集(gpt-translated-pdf-zh)

项目核心特点 该项目专注于提供计算机科学与人工智能领域的高质量中文翻译资源&#xff0c;以下为关键特性&#xff1a; 主题覆盖广泛&#xff1a;包含算法、数据结构、概率统计等基础内容&#xff0c;以及深度学习、强化学习等前沿研究方向。格式统一便捷&#xff1a;所有文…...

JSR 303(即 Bean Validation)是一个通过​​注解在 Java Bean 上定义和执行验证规则​​的规范

&#x1f6e0;️ 一、JSR 303是什么&#xff1f; JSR 303&#xff08;Java Specification Requests 303&#xff09;是Java EE 6的子规范&#xff0c;全称​​Bean Validation​​。它通过注解方式对JavaBean的属性值进行标准化校验&#xff0c;例如检查非空、长度、格式等规则…...

5G 网络中的双向认证机制解析

一、5G 网络中的双向认证机制解析 在 5G 核心网中,双向认证是指UE(用户设备)与网络互相验证对方身份的过程。这一机制通过多层次的安全协议和密钥交换,确保通信双方的合法性,防止中间人攻击和身份伪造。 1. UE 存储的关键信息 UE 作为用户终端,存储以下核心安全信息:…...

DAY07:Vue Router深度解析与多页面博客系统实战

第一部分&#xff1a;Vue Router核心概念深度剖析 1.1 现代前端路由的本质 在单页应用&#xff08;SPA&#xff09;时代&#xff0c;前端路由扮演着至关重要的角色。它突破了传统多页面应用的跳转方式&#xff0c;通过以下机制实现无刷新页面切换&#xff1a; Hash模式&#…...

Drawio编辑器二次开发

‌ Drawio &#xff08;现更名为 Diagrams.net &#xff09;‌是一款完全免费的在线图表绘制工具&#xff0c;由 JGraph公司 开发。它支持创建多种类型的图表&#xff0c;包括流程图、组织结构图、UML图、网络拓扑图、思维导图等&#xff0c;适用于商务演示、软件设计等多种场景…...

1.测试过程之需求分析和测试计划

测试基础 流程 1.分析测试需求 2.编写测试计划 3.设计与编写测试用例 4.执行测试 5.评估与总结 测试目标 根据测试阶段不同可分为四个主要目标&#xff1a;预防错误&#xff08;早期&#xff09;、发现错误&#xff08;开发阶段&#xff09;、建立信心&#xff08;验收阶段&a…...