GO语言的垃圾回收机制
内存垃圾的产生
程序在内存上被分为堆区、栈区、全局数据区、代码段、数据区五个部分。对于C++等早期编程语言栈上的内存回由编译器负责管理回收,而堆上的内存空间需要编程人员负责申请和释放。在Go中栈上内存仍由编译器负责管理回收,而堆上的内存由编译器和垃圾收集器负责管理回收,给编程人员带来了极大的便利性。
垃圾是指程序向堆栈申请的内存空间,随着程序的运行已经不再使用这些内存空间,这时如果不释放它们就会造成垃圾,也就是内存泄漏。
package main//假设每个人都拥有自己都一部手机type Person struct {phone *Phone}type Phone struct {money int}func main() {//定义一个Person为超超chao := new(Person)//超超一开始用的是iphone12iphone := &Phone{money: 6599}chao.phone = iphone//华为推出了鸿蒙,于是超超果断入了一部mate40huawei := &Phone{money: 5899}chao.phone = huawei}
随着超超将手机从iphone换成了华为,phone指向的内存空间就变成了垃圾,这时就需要对phone指向的内存空间进行回收,否则就变成了内存泄漏。
Golang垃圾回收机制
Go1.3采用的标记清除法,Go1.5采用三色标记法,Go1.8采用三色标记法+混合写屏障。
标记清除法
分为两个阶段:标记和清除
标记阶段:从根对象出发寻找并标记所有存活的对象。
清除阶段:遍历堆中的对象,回收未标记的对象,并加入空闲链表
缺点:需要暂停程序STW
步骤:
- 进行STW(暂停程序业务逻辑),然后从main函数开始找到不可达的内存占用和可达的内存占用
- 开始标记,程序找出可达内存占用并标记
- 标记结束,清除未标记的内存占用
- 结束STW停止暂停,让程序继续执行,循环该过程直到main生命周期结束。
一开始的做法是将垃圾清理结束时才停止STW,后来优化了方案将清理垃圾放到了STW之后,与程序运行同时进行,这样做减少了STW的时长。但是STW会暂停用户逻辑对程序的性能影响是非常大的,这种粒度的STW对于性能较高的程序还是无法接受,因此Go1.5采用了三色标记法优化了STW。
三色标记法
将对象标记为白色,灰色和黑色
白色:不确定对象(默认色) ;黑色:存活对象;灰色:存活对象,子对象待处理
步骤:
- 将所有对象标记为白色
- 从根节点集合出发,将第一次遍历到的节点标记为灰色放入到集合列表中
- 遍历灰色集合,将灰色节点遍历到的白色节点标记为灰色,并把灰色节点标记为黑色、
- 循环整个过程
- 直到灰色节点集合为空,回收所有白色节点
这种方法有个缺陷:如果对象的引用被用户修改了,那么之前的标记就无效了。
分析bug的根源所在,主要是因为程序在运行过程中出现了下面俩种情况
- 一个白色对象被黑色对象引用
- 灰色对象与它之间的可达关系的白色对象遭到破坏
因此在此基础上拓展出了俩种方法,强三色不变式和弱三色不变式
- 强三色不变式:不允许黑色对象引用白色对象
- 弱三色不变式:黑色对象可以引用白色,白色对象存在其他灰色对象对他的引用,或者他的链路上存在灰色对象
为了实现这俩种不变式的设计思想,从而引出了屏障机制,即在程序的执行过程中加一个判断机制,满足判断机制则执行回调函数。
屏障机制分为插入屏障和删除屏障,插入屏障实现的是强三色不变式,删除屏障则实现了弱三色不变式。值得注意的是为了保证栈的运行效率,屏障只对堆上的内存对象启用,栈上的内存会在GC结束后启用STW重新扫描。
插入屏障:对象被引用时触发的机制,当白色对象被黑色对象引用时,白色对象被标记为灰色(栈上对象无插入屏障)
缺点在于:如果对象1在栈上新创建了一个对象6,由于栈没有屏障机制,所以对象6仍为白色节点会被回收
所以栈在GC迭代结束时(没有灰色节点),会对栈执行STW,重新进行扫描清除白色节点。(STW时间为10-100ms)
删除屏障:对象被删除时触发的机制。如果灰色对象引用的白色对象被删除时,那么白色对象会被标记为灰色。
缺点:这种做法回收精度较低,一个对象即使被删除仍可以活过这一轮再下一轮被回收。(如果对象4没有引用对象3,此时对象3应该作为垃圾被回收,但是对象3却要等到下一轮GC才会被回收)
同样也存在对栈的二次扫描影响程序的效率。
三色标记+混合写屏障技术
基于插入写屏障和删除写屏障在结束时需要STW来重新扫描栈,所带来的性能瓶颈,Go在1.8引入了混合写屏障的方式实现了弱三色不变式的设计方式,混合写屏障分下面四步
- GC开始时将栈上可达对象全部标记为黑色(不需要二次扫描,无需STW)
- GC期间,任何栈上创建的新对象均为黑色
- 被删除引用的对象标记为灰色
- 被添加引用的对象标记为灰色
相关文章:

GO语言的垃圾回收机制
内存垃圾的产生 程序在内存上被分为堆区、栈区、全局数据区、代码段、数据区五个部分。对于C等早期编程语言栈上的内存回由编译器负责管理回收,而堆上的内存空间需要编程人员负责申请和释放。在Go中栈上内存仍由编译器负责管理回收,而堆上的内存由编译器…...

vim粘贴内容格式混乱解决方法
问题 复制本地文件内容后,咱贴到vim文本内,格式错乱 解决方法 打开vim配置文件 最后面加入一行 vim /etc/vimrc set pastetoggle<F11> 开发vim文件,进入后先按F11进入交互模式 shift insert 再次粘贴 解决...

基于Orangepi 3 lts 的云台相机
利用orangepi 3 lts 和arduino nano 制作了一个云台相机,可用于室内监控。 硬件: orangepi 3 ,arduino nano ,usb相机,180度舵机两个 WeChat_20230806213004 软件: 整体采用mqtt进行消息的中转。 相机采用python 利用opencv…...
Go重写Redis中间件 - Go实现Redis持久化
GO实现Redis持久化 项目开发到这里,我们的下一步就是实现Redis的持久化落盘功能,Redis是一个内存型的数据库,在之前我们实现的单机版Redis如果把进程杀掉,我们通过GET、SET指令存储的数据都将不复存在,数据只存在内存的map里面,重启之后什么都没有了 我们现在的目标就是…...

单元测试之 - Review一个微服务的单元测试
这里以github上一个microservice的demo代码为例,来看看如何为一个完整的服务编写单元测试。具体代码如下所示,我们重点查看一下catalog和customer,order中的单元测试有哪些。 首先来看catalog服务的单元测试,这个服务下面主要编写了CatalogWe…...

NetSuite 2023.2 Cash 360 功能更新
大约一年前,Cash 360功能推出。我们写了篇介绍: NetSuite Cash 360_netsuite oneworld数据可以迁移到sap上吗_NetSuite知识会的博客-CSDN博客Cash 360是在SuiteWorld 2021做的预告,本来是要跟着22.1发布出来,但是各种原因导致跳票…...

vue2-组件和插件的区别
1、组件是什么? 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在vue中每一个.vue文件都可以被视为一个组件。 组件的优势: 降低整个系统的耦合度,在保持接口不变的情况下…...
neo4j查询语言Cypher详解(一)--语法和子句
前言 neo4j的图查询语言叫Cypher。Cypher的独特之处在于它提供了一种匹配模式和关系的可视化方式。 (nodes)-[:ARE_CONNECTED_TO]->(otherNodes)使用圆角括号表示节点(nodes), -[:ARROWS]->表示关系。 语法 解析 Cypher解析器接受任意输入字符串。 unico…...

PCIe总线详解
一、PCIe简介 PCI Express (peripheral component interconnect express) 简称PCIe,是一种高速、串行、全双工、计算机扩展总线标准,采用高速差分总线,并采用端到端的连接方式,因此在每一条PCIe链路中两端只能各连接一个设备。相对…...

【vim 学习系列文章 4 - vim与系统剪切板之间的交互】
文章目录 背景1.1.1 vim支持clipboard 检查1.1.2 vim的寄存器 上篇文章:【vim 学习系列文章 3 - vim 选中、删除、复制、修改引号或括号内的内容】 背景 从vim中拷贝些文字去其它地方粘贴,都需要用鼠标选中vim的文字后,Ctrlc、Ctrlv&#x…...
代码随想录算法训练营第五十六天| 583. 两个字符串的删除操作 72. 编辑距离
代码随想录算法训练营第五十六天| 583. 两个字符串的删除操作 72. 编辑距离 一、力扣583. 两个字符串的删除操作 题目链接 思路:相等时不删除,不相等时,两个字符串各删除一个,比大小,删除用步骤少的。 class Soluti…...

Mac强制停止应用
有时候使用Mac的时候,某个应用卡住了,但是肯定不能因为一个应用卡住了, 就将电脑重启吧,所以只需要单独停止该应用即可,使用快捷键optioncommandesc就会出现强制停止的界面,选择所要停止的应用,…...
Linux系统Redis的哨兵架构配置
Linux系统Redis的哨兵架构配置 此处基于 Linux系统Redis的主从架构配置 进行哨兵高可用架构的搭建 此案例在一台虚拟机上启动6379和6380和6381三个reids主从实例(6379为主节点,6380和6381为从节点),以及26379、26380、26381的sent…...

HarmonyOS/OpenHarmony-ArkTS基于API9元服务开发快速入门
一、创建项目 二、创建卡片 三、添加资源 四、具体代码 Entry Component struct WidgetNewCard {/** The title.*/readonly TITLE: string harmonyOs;readonly CONTEXT: string 技术构建万物智联;/** The action type.*/readonly ACTION_TYPE: string router;/** The…...

macbook怎么卸载软件?2023年最新全新解析macbook电脑怎样删除软件
macbook怎么卸载软件?2023年最新全新解析macbook电脑怎样删除软件。关于Mac笔记本如何卸载软件_Mac笔记本卸载软件的四种方法的知识大家了解吗?以下就是小编整理的关于Mac笔记本如何卸载软件_Mac笔记本卸载软件的四种方法的介绍,希望可以给到…...

c51单片机16个按键密码锁源代码(富proteus电路图)
注意了:这个代码你是没法直接运行的,但是如果你看得懂,随便改一改不超过1分钟就可以用 #include "reg51.h" #include "myheader.h" void displayNumber(unsigned char num) {if(num1){P10XFF;P10P11P14P15P160;}else if…...
GraalVM
一、GraalVM GraalVM 是由 Oracle 开发的一个高性能、高效的通用虚拟机。它是一个全球性的项目,涵盖了多种编程语言和平台,并为开发者提供了一种统一的虚拟机环境。GraalVM 的核心特性是支持多语言混合执行,即在同一个运行时环境中同时执行多…...

File 类和 InputStream, OutputStream 的用法总结
目录 一、File 类 1.File类属性 2.构造方法 3.普通方法 二、InputStream 1.方法 2.FileInputStream 三、OutputStream 1.方法 2.FileOutputStream 四、针对字符流对象进行读写操作 一、File 类 1.File类属性 修饰符及类型属性说明static StringpathSeparator依赖于系统的路…...

开源进展 | WeBASE v3.1.0发布,新增多个实用特性
WeBASE是一个友好、功能丰富的区块链中间件平台,通过一系列通用功能组件和实用工具,助力社区开发者更快捷地与区块链进行交互。 目前WeBASE已更新迭代至v3.1.0版本,本次更新中,WeBASE带来了最新的合约Java脚手架导出功能ÿ…...
C++动态加载 插件
动态加载(Dynamic Loading)是指在程序运行时,根据需要动态地加载和链接代码或资源。 动态加载的主要目的是实现程序的灵活性和可扩展性,以及减少内存消耗和启动时间。通过动态加载,程序可以根据运行时的需求加载特定的…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

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