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、被添加的对象标记为灰色。

满足

变形的弱三色不变式.

插入写屏障  的图作对比

新加入的栈节点也为黑

删除写屏障  的图作对比

避免 某些对象多存活一轮

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

举个栗子!Tableau 技巧(276):学做径向柱状图(Radial Column Chart)

关于 径向柱状图(Radial Column Chart),俗称环形柱状图。它的用法跟柱形图基本一致,不同之处在于它的值刻度是环形的,数值从内到外依次增加,柱子越长代表数值越大。 数据粉可能会问:径向柱形图…

独具韵味的移动端 UI 风格

独具韵味的移动端 UI 风格

10.GLM

智谱AI GLM 大模型家族 最强基座模型 GLM-130B GLM (General Language Model Pretraining with Autoregressive Blank Infilling) 基于自回归空白填充的通用语言模型(GLM)。GLM通过增加二维位置编码并允许以任意顺序预测跨度来改进空白填充预训练&…

SQL 截取函数

目录 1、substring 2、left 3、right 4、substring_index 1、substring 用途:字段截取从指定开始的字符开始,截取要的数;指定开始的字符数字可以用负的,指定开始的字符从后往前(向左)数,截取要的数不能为负。 语…

go语言 | 快速生成数据库表的 model 和 queryset

就是生成 model 目录的 xxx.go 和 xxx_gen.go 文件 使用的工具: 快速生成 model:gentool:https://github.com/go-gorm/gen/tree/master/tools/gentool 根据 model 生成 queryset:go-queryset:https://github.com/jirfa…

2024.6.13 作业 xyt

今日作业: 自由发挥登录窗口的应用场景,实现一个登录窗口界面 要求:每行代码都有注释 #include "my06zuoye.h"My06zuoye::My06zuoye(QWidget *parent): QMainWindow(parent) {//设置大小(窗口&#xf…

java1.8运行arthas-boot.jar运行报错解决

报错内容 输入java -jar arthas-boot.jar,后报错。 [INFO] JAVA_HOME: D:\developing\jdk\jre1.8 [INFO] arthas-boot version: 3.7.2 [INFO] Can not find java process. Try to run jps command lists the instrumented Java HotSpot VMs on the target system.…

诚邀加盟!2025-CISP深圳国际体育展展位预定开启,共享发展机遇

2025-CISP深圳国际体育展定档官宣于2025年2月27-3月1日在深圳(福田)会展中心隆重开幕!招商工作正式开启! 体育创新融入现代生活,打造全球体育创新企业发布产品信息、展示前沿科技及倡导科学运动生活方式的全新平台。届…

为中小制造企业注入数字化转型活力

劳动力成本上升,原材料价格上涨,企业生产成本逐年增加,市场竞争越来越激烈,传统的中小制造企业面临着巨大的压力。 通过数字化转型应对环境的变化已成为行业共识,在数字化的进程中,中小企业首要考虑生存问题,不能沿用…

RPC(远程过程调用):技术原理、应用场景与发展趋势

摘要: RPC(Remote Procedure Call)是一种通信协议,用于实现跨网络的进程间通信。它提供了一种简单高效的方式,使得分布式系统中的不同组件能够像调用本地函数一样调用远程函数。本篇博客将介绍RPC的基本概念&#xff0…

【主要推荐算法概览,包括召回与排序】

文章目录 1、基于内容的推荐协同过滤推荐两大类2、召回算法2.1、基于规则策略的召回2.2、5类基础召回算法2.2.1、关联规则召回算法2.2.2、聚类召回算法2.2.3、朴素贝叶斯召回算法2.2.4、协同过滤召回算法2.2.5、矩阵分解召回算法 2.3、基于复杂算法的召回2.3.1、嵌入方法召回&a…

springboot+vue3前后端项目-部署Docker详解

一、后端yml环境配置 mysql和redis的连接之前是localhost。现在我们需要修改成容器之间的调用,如何知道mysql和redis的连接地址呢?docker compose就帮我们解决了这个问题,我们可以使用镜像容器的服务名称来表示链接。比如docker-compose.yml…

龙芯+RT-Thread+LVGL实战笔记(36)——密码锁完善

【写在前面】不知不觉中,又临近学期末了。这个学期,因为一些特殊原因,一直没怎么更新本教程,而且不得已上调了本教程的价格,在此笔者深表歉意。另一方面,自己带的学生发挥不佳,很遗憾未能闯进国赛,为此笔者也郁闷了相当长一段时间。事已至此,也只能慢慢释然,来年再战…

每日一练:攻防世界:Misc文件类型

给了一个txt文本文件,因为题目是文件类型,我先开始一直在想关于文件头的知识。 这串数据看着像十六进制数据,我就直接把他转ASCII了 反转一下就是base64,因为base64没有_,所以去掉46ESAB_,base64解码Hex试…

汇聚荣科技有限公司在拼多多评价上好不好?

汇聚荣科技有限公司在拼多多平台的评价如何,这是很多消费者在选择购买该公司产品时会关心的问题。通过深入分析,我们可以从多个维度来探讨这一问题。 一、产品质量 对于任何公司而言,产品的质量是其生存和发展的根本。根据用户反馈和相关评价…

联邦学习权重聚合,联邦学习权重更新

目录 联邦学习权重聚合 model.state_dict() 保存模型参数 加载模型参数 注意事项 联邦学习权重更新 联邦学习权重聚合 model.state_dict() 在PyTorch框架中,model.state_dict() 是一个非常重要的方法,它用于获取模型的参数(即权重和偏置)作为一个有序字典(Order…

基础-01-计算机网络概论

一. 计算机网络的发展与分类 1.计算机网络的形成与发展 计算机网络:计算机技术与通信技术的结合 ICTITCT 2.计算机网络标准阶段 3.计算机网络分类1:通信子网和资源子网 通信子网:通信节点(集线器、交换机、路由器等)和通信链路(电话线、同轴电缆、无线电线路、卫…

VMware安装Debian,Debian分区,虚拟机使用NAT模式联网,Linux设置静态IP

官网 https://www.debian.org/download stable是稳定版 win下amd64就行,macOs装arm架构的 安装Debian虚拟机 教程里没有的只管往下点就完了 哪个都行 选镜像 选安装位置 别超过宿主机内核就行 看你需求 NAT模式 虚拟 看你需求 其他的也检查一下 图形安装 选中文 继…

swift5 在当前控制器先dismiss后pop

如下图需要在present当前控制器时用全局变量firmwareUpgradePresentingVC先引用上一个控制器(下面的代码亲测有效) func dismissAndPop() {self.dismiss(animated: false) {firmwareUpgradePresentingVC.navigationController!.popViewController(animat…

书生·浦语大模型实战营第二期作业一

书生葡语大模型实战营介绍,第二期课程内容: 通用大模型成为人工智能发展趋势: 书生浦语大模型开源历程: 书生浦语大模型体系: 书生葡语大模型2.0提供不同尺寸和类型的模型,支持多语言和多模态任务&#xff…