Golang的GC

目录

介绍GC

概要

什么是根对象

三色标记法

什么情况下三色标记法会失效

屏障机制

“强-弱” 三色不变式

插入屏障 (强三色)

 删除屏障(弱三色)

Go 的混合写屏障机制

混合写屏障规则


 

介绍GC

概要

  • 作用范围:只回收堆内存,不回收栈内存(函数执行完毕后直接释放)
  • 主流 GC 算法:引用计数(Python)、分代收集(Java)、标记-清除(Golang 使用三色标记法)
  • 触发时机:
  • 主动触发:调用 runtime.GC()
  • 被动触发:定时触发(默认为 2 分钟)、当前堆内存占用为上次 GC 后内存占用的两倍

什么是根对象

全局变量:编译器就能确定存在于程序整个生命周期的变量

执行栈:每个 goroutine 都有自己的执行栈,执行栈上包含栈上的变量及指向分配的堆内存指针


寄存器: 寄存器的值可能表示一个指针,参与计算的这些指针可能指向某些赋值器分配的堆内存块

三色标记法

Golang中的垃圾回收主要应用三色标记法,GC过程和其他用户goroutine可并发运行,但需要一定时间的STW(stop the world)

所谓三色标记法实际上就是通过三个阶段的标记来确定清楚的对象都有哪些?

我们来看一下具体的过程。

第一步 , 每次新创建的对象,默认的颜色都是标记为“白色”,如图所示。

 第二步, 每次GC回收开始, 会从根节点开始遍历所有对象,把遍历到的对象从白色集合放入“灰色”集合如图所示。

如果 本次到 对象1 和 对象4 便遍历完,本次GC结束

第三步, 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合,如图所示。

第四步,重复上面的步骤我们可以得到如下

剩下的就是全部依赖的黑色对象,然后我们把白色的对象删除,本轮GC 结束

什么情况下三色标记法会失效

以下条件在三色标记法中,是不希望被发生的。

条件1: 一个白色对象被黑色对象引用(白色被挂在黑色下)

条件2: 灰色对象与它之间的可达关系的白色对象遭到破坏(灰色同时丢了该白色)

如果当以上两个条件同时满足时,就会出现对象丢失现象!

如图所示,对象2原本指向对象3,但是丢了对象3      黑色对象4 已经完成扫描了,但是对象3挂在上面

这就导致 对象三 没有被扫描 变成灰色 进入 灰色表内,导致被GC给“误杀”回收掉了。

 为了防止这种现象的发生,最简单的方式就是STW,直接禁止掉其他用户程序对对象引用关系的干扰,但是STW的过程有明显的资源浪费,对所有的用户程序都有很大影响

那么是否可以在保证对象不丢失的情况下合理的尽可能的提高GC效率,减少STW时间呢?

答案是可以的,我们只要使用一种机制,尝试去破坏上面的两个必要条件就可以了。

屏障机制

“强-弱” 三色不变式

强三色不变式

不存在黑色对象引用到白色对象的指针。

强三色不变色实际上是强制性的不允许黑色对象引用白色对象,就不会出现有白色对象被误删况。

弱三色不变式

弱三色不变式强调,黑色对象可以引用白色对象,但是这个白色对象必须存在其他灰色对象对它的引用,或者可达它的链路上游存在灰色对象。 这样实则是黑色对象引用白色对象,白色对象处于一个危险被删除的状态,但是上游灰色对象的引用,可以保护该白色对象,使其安全。

插入屏障 (强三色)

具体操作:在A对象引用B对象的时候,B对象被标记为灰色。(将B挂在A下游,B必须被标记为灰色)

满足:强三色不变式. (不存在黑色对象引用白色对象的情况了, 因为白色会强制变成灰色)

流程:

对于 堆对象来说 新挂上的对象标记为灰色,如图所示 对象3原本为白,被标记为灰 

栈对象来说: 如图 新加入的 对象8 为白色 挂在黑色对象1上

如果栈不添加,当全部三色标记扫描之后,栈上有可能依然存在白色对象被引用的情况(如上图的对象8).  所以要对栈重新进行三色标记扫描, 但这次为了对象不丢失, 要对本次标记扫描启动STW暂停. 直到栈空间的三色标记结束.

 删除屏障(弱三色)

具体操作: 被删除的对象,如果自身为灰色或者白色,那么被标记为灰色。

满足: 弱三色不变式. (保护灰色对象到白色对象的路径不会断)

会导致什么呢?  本应该被清理的 对象2 偷偷活过了这一轮 GC 检查 

这种方式的回收精度低,一个对象即使被删除了最后一个指向它的指针也依旧可以活过这一轮,在下一轮GC中被清理掉。

Go 的混合写屏障机制

插入写屏障和删除写屏障的短板:

插入写屏障:结束时需要STW来重新扫描栈,标记栈上引用的白色对象的存活; 
删除写屏障:回收精度低,GC开始时STW扫描堆栈来记录初始快照,这个过程会保护开始时刻的所有存活对象。 

Go V1.8版本引入了混合写屏障机制,避免了对栈重新检查的过程,极大的减少了STW的时间。结合了两者的优点。

混合写屏障规则

具体规则

1、GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW),

2、GC期间,任何在栈上创建的新对象,均为黑色。

3、被删除的对象标记为灰色。

4、被添加的对象标记为灰色。

满足

变形的弱三色不变式.

插入写屏障  的图作对比

新加入的栈节点也为黑

删除写屏障  的图作对比

避免 某些对象多存活一轮

总结:栈上的对象(包括其引用对象)赦免,堆上的对象既进行插入屏障,又进行删除屏障 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/697725.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

亚马逊冗余库存处理

在亚马逊放置90天以上的产品,又不在正常的动销,就要采取一定的措施了。清库存方式: 最直接的方式——降价促销(至少要降价百分之三十以上,库龄越久,降价越狠)参加官方的活动促销的话是需要符合…

Python学习笔记速成版

数据容器 列表的方法-总览 具体操作 元组 定义 相关操作 注意事项 特点 字符串 总览 常用操作 特点 序列 定义 切片操作 Set集合 总览 定义 常用操作 注意事项 字典 总览 定义 常用操作 获取 嵌套 其他操作 summary 通用操作 字符串大小比较 函数进阶 多个返回值 多种传…

2024年江苏三支一扶公告已出,招440人!

本次江苏省将招募440名高校毕业生,安排到乡镇(街道)从事支教、支农、支医、帮扶乡村振兴、水利、就业和社会保障服务工作(以下简称“三支一扶”计划),服务期限为2年。 招募程序 招募工作按照个人报名、资格…

Ansible离线部署 之 Zabbix

Ansible介绍 Ansible 是一个自动化平台,用于 IT 自动化,如配置管理、应用部署、任务自动化等。Ansible 使用 SSH 来连接到远程机器,并执行预定义的任务。Ansible 的主要特点是其简单性、易用性和强大的功能集。 以下是 Ansible 的一些关键特…

Mysql学习(八)——多表查询

文章目录 五、多表查询5.1 多表关系5.2 多表查询概述5.3 内连接5.4 外连接5.5 自连接5.6 联合查询5.7子查询5.8 总结 五、多表查询 5.1 多表关系 概述:项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,…

接口请求的六种常见方式详解(get、post、head等)

一.接口请求的六种常见方式: 1、Get 向特定资源发出请求(请求指定页面信息,并返回实体主体) 2、Post 向指定资源提交数据进行处理请求(提交表单、上传文件),又可能导致新的资源的建…

基于大模型的360度全景图像生成技术:L-MAGIC

在数字技术的浪潮中,我们迎来了一项革命性的创新——L-MAGIC,一个能够基于一张普通照片和简单文字描述,快速生成360度全方位全景画面的系统。L-MAGIC不仅提供了沉浸式的视觉体验,还融合了多种素材和技术手段,让全景图像的生成变得更加丰富和真实。 技术亮点 1. 多角度视…

SpringMVC01-初始SpringMVC

SpringMVC 回顾MVC 什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式,MVC是一种架构模…

[FreeRTOS 基础知识] 保存现场与恢复现场

文章目录 什么是现场?保存现场的数据存放在哪里?保护现场的场景 什么是现场? 在[FreeRTOS 基础知识] 栈 与 汇编语言文章中解析了fun_c汇编函数,假设在执行fun_c函数的过程中产生高优先级的中断。如下图所示。 此时刚从RAM的SP栈…

[大模型]GLM4-9B-chat Lora 微调

本节我们简要介绍如何基于 transformers、peft 等框架,对 LLaMA3-8B-Instruct 模型进行 Lora 微调。Lora 是一种高效微调方法,深入了解其原理可参见博客:知乎|深入浅出 Lora。 这个教程会在同目录下给大家提供一个 nodebook 文件&#xff0c…

【docker】 pull access denied for alpine-java, repository does not exist

问题: com.spotify.docker.client.exceptions.DockerException: pull access denied for alpine-java, repository does not exist or may require docker login: denied: requested access to the resource is denied org.apache.maven.plugin.MojoExecutionExce…

[Algorithm][动态规划][完全背包问题][零钱兑换][零钱兑换Ⅱ][完全平方数]详细讲解

目录 1.零钱兑换1.题目链接2.算法原理详解3.代码实现 2.零钱兑换 II1.题目链接2.算法原理详解3.代码实现 3.完全平方数1.题目链接2.算法原理详解3.代码实现 1.零钱兑换 1.题目链接 零钱兑换 2.算法原理详解 思路: 确定状态表示 -> dp[i][j]的含义 dp[i][j]&am…

Gitlab安装配置

gitlab git是一个分布式的代码版本管理软件。用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 1.版本控制 是指对软件开发过程中各种程序代码,配置文件及说明文档等文件变更的管…

如何用R语言ggplot2画高水平期刊散点图

文章目录 前言一、数据集二、ggplot2画图1、全部代码2、细节拆分1)导包2)创建图形对象3)主题设置4)轴设置5)图例设置6)散点颜色7)保存图片 前言 一、数据集 数据下载链接见文章顶部 处理前的数据…

LabVIEW图像采集处理项目中相机选择与应用

在LabVIEW图像采集处理项目中,选择合适的相机是确保项目成功的关键。本文将详细探讨相机选择时需要关注的参数、黑白相机与彩色相机的区别及其适用场合,帮助工程师和开发者做出明智的选择。 相机选择时需要关注的参数 1. 分辨率 定义:分辨率…

上心师傅的思路分享(三)--Nacos渗透

目录 1. 前言 2. Nacos 2.1 Nacos介绍 2.2 鹰图语法 2.3 fofa语法 2.3 漏洞列表 未授权API接口漏洞 3 环境搭建 3.1 方式一: 3.2 方式二: 3.3 访问方式 4. 工具监测 5. 漏洞复现 5.1 弱口令 5.2 未授权接口 5.3.1 用户信息 API 5.3.2 集群信息 API 5.3.3 配置…

Functional ALV系列 (10) - 将填充FieldCatalog封装成函数

在前面的博文中,已经讲了封装的思路和实现,主要是利用 cl_salv_data_descr>read_structdescr () 方法来实现。在这里,贴出代码方便大家参考。 编写获取内表组件的通用方法 form frm_get_fields using pt_data type any tablechanging…

微信小程序双层/多层 wx:for 循环嵌套,关于内外层的 index 和 item ;data-index 传递两个参数

微信小程序用 wx:for 循环可以快速将后端 js 的数组快速显示到前端&#xff1b; 那假如数组中嵌套数组&#xff1b;就存在内外层两层及以上的多层嵌套循环了。 那么如果两层的嵌套式循环 index 究竟是属于哪一层呢&#xff1f;item 又属于哪一个呢&#xff1f; <view><…

java之面向对象2笔记

1 接口(interface) 1.1 概述 接口&#xff08;Interface&#xff09;在计算机科学中&#xff0c;特别是在面向对象编程&#xff08;OOP&#xff09;中&#xff0c;是一个重要的概念。它定义了一组方法的规范&#xff0c;但没有实现这些方法的具体代码。接口的主要目的是确保类…

介绍Linux

目录 1.什么是操作系统 2.现实生活中的操作系统 3.操作系统的发展史 4.操作系统的发展 Linux的不同版本以及应用领域 1.Linux内核及发行版介绍 <1>Linux内核版本 <2>Linux发行版本 2.应用领域 个⼈桌⾯领域的应⽤ 服务器领域 嵌⼊式领域 3.文件和目录 …