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

Golang中GC和三色屏障机制【Golang面试必考】

文章目录

    • Go v1.3 标记—清楚(mark and sweep)方法
    • Go V1.5 三色标记法
    • 三色标记过程无STW的问题
    • 强弱三色不变式
    • 插入写屏障
    • Go V1.8的三色标记法+混合写屏障机制
    • 混合写屏障场景
      • 场景1:对象被一个堆对象删除引用,成为栈对象的下游
      • 场景2:对象被一个栈对象删除引用,成为另一个新建栈对象的下游
      • 场景3:对象被一个堆对象删除引用,成为另一个堆对象的下游
      • 场景4:对象从一个栈对象删除引用,成为另一个堆对象的下游
    • 总结

Go v1.3 标记—清楚(mark and sweep)方法

  • 主要流程

    • 暂停程序业务逻辑,找出可达对象和不可达对象;
    • 开始标记,程序找出它所有可达的对象,并做上标记;
    • 标记完了之后,然后开始清除未标记的对象;
    • 停止暂停,让程序继续跑,然后循环重复这个过程,直到process程序声明周期结束;
  • 标记清除整体逻辑

在这里插入图片描述

  • 标记清除的缺点

    • STW,stop the world ;让程序暂停,程序出现卡顿
    • 标记需要扫描整个heap;
    • 清楚数据会产生heap碎片;【如果地址不连续】

    其中最大的问题还是因为STW太费时间,早期的探索是通过将sweep阶段移到STW之外,这确实是一种改善的方法,但是始终难以改变这种低级效能。所以需要尝试采用新的标记模式来代替清楚标记法(mark-sweep)—三色标记法。

在这里插入图片描述

Go V1.5 三色标记法

  • 主要流程

在这里插入图片描述

在这里插入图片描述

主要的流程如下【广度优先搜索】:

  • 只要是新创建的对象,默认的颜色都是标记为"白色";
  • 每次GC回收开始,然后从根节点开始遍历所有对象,把遍历到的对象从白色集合中放入"灰色"集合中;
  • 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将原先的灰色对象放入黑色集合当中;
  • 重复第三步,直到灰色中无任何对象;
  • 回收所有白色标记表的对象,也就是回收垃圾;

三色标记过程无STW的问题

  • 如果三色标记中不启动STW会怎么样?

在这里插入图片描述

简单来说,就是没有STW,那么如果对象2对对象3依赖的指针取消了,而对象四新建了一个对对象3的依赖,那么按照之前的原则,每次都是对灰色节点进行遍历,所以这个时候,无法将对象3标记为灰色,故会造成错误。

  • 三色标记最不希望发生的事情

    • 条件1:一个白色对象被黑色对象引用(白色挂在黑色下)
    • 条件2:灰色对象与它之间的可达关系的白色对象遭到破坏(灰色同时丢了该白色)

    以上两个条件同时满足就会发生对象的丢失。因此有必要使用STW,但是应当尽可能的提高GC效率,减少STW时间。

在这里插入图片描述

强弱三色不变式

  • 强三色不变式

    强制性的不允许黑色对象引用白色对象。

  • 弱三色不变式

    黑色对象可以引用白色对象,但是白色对象存在其他灰色对象对它的引用,或者可达它的链路上游存在灰色对象。

在三色标记中如果满足强/弱之一,即可保证对象不丢失。为了使用上面这种思想,引入了屏障

插入写屏障

  • 屏障的理解
    在这里插入图片描述

  • 屏障机制

    • 插入屏障:对象被引用的时候触发的机制

      在A对象引用B对象的时候,B对象被标记为灰色(将B挂在A下游,B必须被标记为灰色)【强三色不变式】

      // 伪码
      添加下游对象(当前下游对象slot,新下游对象ptr){// 1标记灰色(新下游对象)// 	2当前下游对象slot = 新下游对象ptr
      }
      

      ⭐️⭐️⭐️一般为了保证效率,不会在栈上使用插入屏障。【栈不触发插入屏障,是因为栈上的内存会随着栈销毁而回收,除非触发内存逃逸】

在这里插入图片描述

也就是说在堆上的对象才会启用插入屏障。在准备回收白色前,重新遍历扫描一边栈空间,此时加STW暂停保护栈,防止有外界干扰(有新的白色被黑色添加)

在这里插入图片描述

插入写屏障的不足就是在结束时需要用STW来重新扫描栈,大约需要10ms~100ms
  • 删除屏障:当引用关系被删除的时候触发的机制

    具体操作:被删除的对象,如果自身或者上游对象为灰色或者白色,那么被标记为灰色【满足弱三色不变式,保护灰色对象到白色对象的路径不会断】

    // 伪代码
    添加下游对象(当前下游对象slot,新下游对象ptr)// 1
    if (当前下游对象slot是灰色 || 当前下游对象slot是白色) {标记灰色(新下游对象ptr)
    }
    // 2
    当前下游对象slot = 新下游对象ptr
    

    删除写屏障的不足之处在于回收精度低,一个对象及时被删除了最后一个指向它的指针也依旧可以活过这一轮,在下一轮GC中被清理掉。

Go V1.8的三色标记法+混合写屏障机制

  • 具体操作

    • GC开始将栈上的对象全部扫描并标记为黑色(之后不在进行第二次重复扫描,无需STW)
    • GC期间,任何在栈上创建的新对象,均为黑色
    • 被删除的对象标记为灰色
    • 被添加的对象标记为灰色

    变形的弱三色不变式(结合插入、删除写屏障两者的优点)

    //伪码
    添加下游对象(当前下游对象slot,新下游对象ptr){// 1标记灰色(当前下游对象slot)// 2标记灰色(新下游对象)// 3当前下游对象slot = 新下游对象ptr
    }
    

混合写屏障场景

场景1:对象被一个堆对象删除引用,成为栈对象的下游

// 伪代码
// 前提:堆对象->对象7 = 对象7;// 对象7 被 对象4 引用
栈对象1->对象7 = 堆对象7;// 将堆对象7挂载在 栈对象 下游
堆对象4->对象7 = null;//对象4 删除引用 对象7 

对象4删除了对象7的引用关系,因为对象4是堆区,所以触发删除屏障,标记被删除的对象7为灰。【注意这个地方不能认为栈里面元素添加一个就直接标记为黑色,因为栈的区域不启用屏障】

场景2:对象被一个栈对象删除引用,成为另一个新建栈对象的下游

(1)、新创建一个对象9在栈上(因为是混合写屏障模式中,GC过程汇总任何在栈中新创建的对象均标记为黑色)

(2)、对象9添加下游引用栈堆对象3(直接添加,栈不启动屏障,无屏障效果)

(3)、对象2删除对象3的引用关系(直接删除,栈不启动写屏障,无屏障效果)

场景3:对象被一个堆对象删除引用,成为另一个堆对象的下游

//伪代码
堆对象10 -> 对象7 = 堆对象7; // 将堆对象7 挂在 堆对象10 下游
堆对象4 -> 对象7 = null; // 对象4 删除引用 对象7

(1)、堆对象10已经扫描标记为黑(黑色情况比较特殊,其他颜色暂不考虑)。

(2)、堆对象10添加下游引用堆对象7,触发屏障机制,被添加的对象标记为灰色,对象7变成灰色(对象6被保护)。

(3)、堆对象删除下游引用堆对象7,触发屏障机制,被删除的对象标记为灰色,对象7被标记为灰色。

场景4:对象从一个栈对象删除引用,成为另一个堆对象的下游

// 伪代码
栈对象1 -> 对象2 = null; // 对象1 删除引用 对象2
栈对象4 -> 对象2 = 栈对象2 // 对象4 添加栈对象2
堆对象 -> 对象7 = null; // 对象4 删除一个对象7

(1)、栈对象1删除对堆对象2的引用。(栈空间不触发写屏障)。

(2)、堆对象将之前引用对象7的关系,转移至对象2(对象4删除对象7的引用关系)。

(3)、对象4在删除的时候,触发写屏障,标记被删除对象7为灰色。保护对象7及其下游节点。

总结

Go V1.3 使用普通标记清除法,整体过程需要STW,效率极其低

Go V1.5 三色标记法,堆空间启动写屏障,栈空间不启动,全部扫描一次后,需要重新扫描一次栈(需要STW),效率极其普通

Go V1.8 三色标记法+混合写屏障机制,堆空间启动,栈空间不启动,整体过程几乎不需要STW,效率较高

相关文章:

Golang中GC和三色屏障机制【Golang面试必考】

文章目录Go v1.3 标记—清楚(mark and sweep)方法Go V1.5 三色标记法三色标记过程无STW的问题强弱三色不变式插入写屏障Go V1.8的三色标记法混合写屏障机制混合写屏障场景场景1:对象被一个堆对象删除引用,成为栈对象的下游场景2:对象被一个栈对象删除引用&#xff0…...

MOS FET继电器(无机械触点继电器)设计输入侧电源时的电流值概念

设计输入侧电源时的问题 机械式继电器、MOS FET继电器分别具有不同的特长。基于对MOS FET继电器所具小型及长寿命、静音动作等优势的需求,目前已经出现了所用机械式继电器向MOS FET继电器转化的趋势。 但是,由于机械式继电器与MOS FET继电器在产品结构…...

5. 驱动开发

文章目录一、驱动开发1.1 前言1.2 何谓驱动框架1.3 内核驱动框架中LED的基本情况1.3.1 相关文件1.3.2 九鼎移植的内核中led驱动1.3.3 案例分析驱动框架的使用1.3.4 典型的驱动开发行业现状1.4 初步分析led驱动框架源码1.4.1 涉及到的文件1.4.2 subsys_initcall1.4.3 led_class_…...

模板方法模式详解

模板方法模式(行为模式) 1. 模板方法模式介绍 父类定义算法骨架,细节的具体实现延迟到子类子类只是定义某些自己的个性化处理,但不改变执行顺序 2. 好处 减少代码冗余,共性抽取后算法流程更加清晰与规范降低流程性…...

关于 Lightweight process container,ChatGPT的答案

晓楚 Can you give me a list of process container? As an AI language model, I can provide you with a list of popular process containers, which are as follows: Docker Kubernetes Apache Mesos LXC OpenVZ systemd-nspawn rkt (Rocket) Linux Containers (LXC) Ga…...

机器学习和深度学习的综述

机器学习和深度学习的综述 1.1.1人工智能、机器学习、深度学习的关系 人工智能(Artificial Intelligence,AI)是最宽泛的概念,是研发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。由于这个定义…...

Synopsys Sentaurus TCAD系列教程之--Sprocess(SmallMOS_2D3D) 解析

SmallMOS_2D3D解析 #header## STI depth set sti_depth 0.15 ## Half STI width set sti_width sti_width ## Half gate length set gate_len <lg/2> ## SD length (from center) set sd_len [expr $gate_len0.05]#endheader## X lines line x location 0.0 spacing 0.…...

好使!NAS中傻瓜式配置反向代理及SSL证书,提升网络安全性!

对于有NAS或者有个人主机的朋友来说&#xff0c;将机器映射到外网是基本操作。 但是一般来说&#xff0c;能直接从外网访问的往往仅有80和443端口。事实上&#xff0c;运营商一般把家庭宽带的这两个端口都封了&#xff0c;所以如果我们想要从外网访问自己家中机器部署的服务&a…...

数据结构队列-先进先出

一&#xff0c;概述 队列这个概念非常好理解。你可以把它想象成排队买票&#xff0c;先来的先买&#xff0c;后来的人只能站末尾&#xff0c;不允许插队。先进者先出&#xff0c;这就是典型的“队列”。 二&#xff0c;顺序队列和链式队列 队列和栈一样&#xff0c;也是一种…...

CentOS 7使用TiUP部署TiDB

本文主要是根据官方文档指导&#xff0c;结合实际主机情况&#xff0c;在Cent OS7上使用TiUP在线部署TiDB。 环境说明 类型操作系统版本配置中控机Deepin 20.34核CPU6G内存40G硬盘TiDB部署机Cent OS 7.38核CPU48G内存100硬盘网络情况中控机与外网相连&#xff0c;中控机与部署…...

java单元测试批处理数据模板【亿点点日志配合分页以及多线程处理】

文章目录引入相关资料环境准备分页查询处理&#xff0c;减少单次批量处理的数据量级补充亿点点日志&#xff0c;更易观察多线程优化查询_切数据版多线程_每个线程都分页处理引入 都说后端开发能顶半个运维&#xff0c;我们经常需要对大量输出进行需求调整&#xff0c;很多时候…...

【数据结构】模拟实现 堆

堆数据结构是一种数组对象&#xff0c;它可以被看作一颗完全二叉树的结构&#xff08;数组是完全二叉树&#xff09;&#xff0c;堆是一种静态结构。堆分为最大堆和最小堆。最大堆&#xff1a;每个父结点都大于孩子结点。最小堆&#xff1a;每个父结点都小于孩子结点。堆的优势…...

Go语言学习的第三天--上部分(基础用法)

前两天经过不断度娘&#xff0c;与对up主的跟踪学习了解了go的历史&#xff0c;今天开始了go的基础&#xff01;&#xff01;本章主要是go 的注释、变量及常量的梳理一、注释不管什么语言都有自己的注释&#xff0c;go也不例外 &#xff01;&#xff01;单行注释 // 多行注释 …...

linux面试基础篇

题目目录1.简述DNS分离解析的工作原理&#xff0c;关键配置2.apache有几种工作模式&#xff0c;分别简述两种工作模式及其优缺点&#xff1f;3.写出172.0.0.38/27 的网络id与广播地址4.写出下列服务使用的传输层协议&#xff08;TCP/UDP&#xff09;及默认端口5.在局域网想获得…...

黑马程序员提高变成

这里写目录标题函数模板1.2.2 函数模板注意事项1.2.3 函数模板案例调用规则类模板与函数模板区别类模板与继承类模板成员函数类外实现#pragma once类模板与友元案例重新定义【】stl2.2 STL基本概念STL六大组件容器算法迭代器初识vectorvector容器嵌套容器string容器string赋值操…...

MySQL5种索引类型

MySQL的类型主要有五种&#xff1a;主键索引、唯一索引、普通索引、空间索引、全文索引 有表&#xff1a; CREATE TABLE t1 ( id bigint unsigned NOT NULL AUTO_INCREMENT, u1 int unsigned NOT NULL DEFAULT 0, u2 int unsigned NOT NULL DEFAULT 0, u3 varchar(20) NOT NU…...

uniapp封装缓存方法,支持类似cookie具有过期时间

1、定义CacheManage类&#xff0c;有set和get方法 class CacheManage {set() {},get() {} }set用来设置缓存&#xff0c;get用来获取缓存 2、完善set业务逻辑 大概逻辑如下&#xff1a; 1、将接收params参数&#xff0c;包含key、data、unit、time key 缓存字段&#xff0c;…...

Jfrog 搭建本地maven仓库以及上传Android库

Jfrog 下载 安装包下载地址&#xff1a;Download Artifactory OSS | JFrog 如果是想下载之前的版本&#xff0c;可以点击上面的Get code source &#xff0c;如果是最新版本&#xff0c;直接点下面的下载就好。下面以Linux安装为例。 Jfrog安装 对于Linux而言&#xff0c;其实…...

日报周报月报工作总结生成器【智能文案生成器】

日报周报月报工作总结生成器【智能文案生成器】 天天写日报&#xff0c;我真的快奔溃了&#xff01; 摸了一天鱼&#xff0c;下班还要写日报&#xff1b; 划了一周的水&#xff0c;周末还要写周报&#xff1b; 啊啊啊啊… 在职场上&#xff0c;尤其是互联网公司里&#xff0c…...

linux日志管理工具logrotate配置

linux日志管理工具logrotate配置logrotate介绍logrotate配置讲解主配置文件解释(/etc/logrotate.conf)logrotete 命令参数添加配置以添加一个nginx配置为例强制启动配置logrotate介绍 logrotate是centos自带工具&#xff0c;其他操作系统可能需要自行安装。logrotate用来进行日…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...