Go语言七篇入门教程七GC垃圾回收三色标记

目录
  • GC
    • 如何判断一个对象是否可达
  • 三色标记法
    • 原理如下

GC

GC全称Garbage Collection

目前主流的垃圾回收算法有两类,分别是追踪式垃圾回收算法(Tracing garbage collection)和引用计数法( Reference counting )。
而三色标记法是属于追踪式垃圾回收算法的一种。

追踪式算法的核心思想是判断一个对象是否可达,因为一旦这个对象不可达就可以立刻被 GC 回收了。

如何判断一个对象是否可达

分为两步:

  • 第一步找出所有的全局变量和当前函数栈里的变量,标记为可达。
  • 第二步,从已经标记的数据开始,进一步标记它们可访问的变量,周而复始,这一过程也叫传递闭包

在go推出三色标记法之前,go所使用的gc算法叫Mark-And-Sweep(标记清扫)

这个算法就是严格按照追踪式算法的思路来实现的。

  • 先设置一个标志位来记录对象是否被使用,最开始所有的标记位都是 0。
  • 如果发现对象是可达的就会置为1,一步步下去就会呈现一个类似树状的结果。
  • 等标记的步骤完成后,会将没有被标记的对象统一清理,再次把所有的标记位设置成 0, 以便下次进行清理。

这个算法最大的问题是 GC 执行期间需要把整个程序完全暂停,不能异步进行GC操作。因为在不同阶段标记清扫法的标志位 0 和 1 有不同的含义,那么新增的对象无论标记为什么都有可能意外删除这个对象。对实时性要求高的系统来说,这种需要长时间挂起的标记清扫法是不可接受的。所以就需要一个算法来解决 GC 运行时程序长时间挂起的问题,那就三色标记法。

三色标记法

三色标记法是传统 Mark-Sweep 的一个改进,它是一个并发的 GC 算法。on-the-fly

原理如下

整个进程空间里申请每个对象占据的内存可以视为一个图, 初始状态下每个内存对象都是白色标记。

stop the world,将扫描任务作为多个并发的goroutine立即入队给调度器,进而被CPU处理,第一轮先扫描所有可达的内存对象,标记为灰色放入队列

第二轮可以恢复start the world,将第一步队列中的对象引用的对象置为灰色加入队列,一个对象引用的所有对象都置灰并加入队列后,这个对象才能置为黑色并从队列之中取出。循环往复,最后队列为空时,整个图剩下的白色内存空间即不可到达的对象,即没有被引用的对象;

第三轮再次stop the world,将第二轮过程中新增对象申请的内存进行标记(灰色),这里使用了writebarrier(写屏障)去记录这些内存的身份;

这个算法可以实现 on-the-fly,也就是在程序执行的同时进行收集,并不需要暂停整个程序。

简化步骤如下:

1、首先创建三个集合:白、灰、黑。

2、将所有对象放入白色集合中。

3、然后从根节点开始遍历所有对象(注意这里并不递归遍历),把遍历到的对象从白色集合放入灰色集合。

因为root set 指向了A、F,所以从根结点开始遍历的是A、F,所以是把A、F放到灰色集合中。

4、之后遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合
我们可以发现这个A指向了B,C,D所以也就是把BCD放到灰色中,把A放到黑色中,而F没有指任何的对象,所以直接放到黑色中。

5、重复 4 直到灰色中无任何对象

因为D指向了A所以D也放到了黑色中,而B和C能放到黑色集合中的道理和F一样,已经没有了可指向的对象了。

6、通过write-barrier检测对象有无变化,重复以上操作

由于这个EGH并没有和RootSet有直接或是间接的关系,所以就会被清除。

7、收集所有白色对象(垃圾)

所以我们可以看出这里的情况,只要是和root set根集合直接相关的对象或是间接相关的对象都不会被清楚。只有不相关的才会被回收。

参考文档:

一张图讲解GC
关于write-barrier写屏障

以上就是Go语言七篇入门教程GC垃圾回收三色标记的详细内容,更多关于Go语言GC垃圾回收三色标记的资料请关注我们其它相关文章!

(0)

相关推荐

  • go:垃圾回收GC触发条件详解

    版本: go version go1.13 darwin/amd64 在go源码runtime目录中找到gcTrigger结构体,就能看出大致调用的位置 GC调用方式 所在位置 代码 定时调用 runtime/proc.go:forcegchelper() gcStart(gcTrigger{kind: gcTriggerTime, now: nanotime()}) 分配内存时调用 runtime/malloc.go:mallocgc() gcTrigger{kind: gcTriggerHe

  • Go语言七篇入门教程四通道及Goroutine

    目录 1. 前言 2. 通道简介 2.1 声明 2.1 读写 2.3 通道详解 2.3.1 例子 2.3.2 死锁 2.3.3 关闭通道 2.3.4 缓冲区 2.3.5 通道的长度和容量 2.3.6 单向通道 2.3.7 Select 2.3.8 default case 块 2.3.9 空 select 2.3.10 Deadlock 2.3.11 nil通道 2.4 多协程协同工作 2.5 WaitGroup 2.5.1 简介 2.5.2工作池 2.5.3 Mutex 3. 结语 如何学习G

  • Go语言七篇入门教程六网络编程

    目录 1. Socket 编程 1.1 Dial()函数 2. HTTP 编程 2.1 HTTP 客户端 2.2 HTTP 服务端 2.2.1 处理 HTTP 请求 3. RPC 编程 3.1 Go 语言中的 RPC 支持与处理 3.2 Gob 简介 3.3 设计优雅的 RPC 接口 1. Socket 编程 在 Go 语言中编写网络程序时,我们将看不到传统的编码形式.以前我们使用 Socket 编程时,会按照如下步骤展开. 建立 Socket:使用 socket()函数. 绑定 Socket:

  • 谈论Go 什么时候会触发 GC问题

    目录 1.什么是 GC 2.为什么要 GC 3.GC 触发场景 3.1系统触发 3.2手动触发 3.3 基本流程 3.4 在哪触发 4.监控线程 5.堆内存申请 在早期经常遭到唾弃的就是在垃圾回收(下称:GC)机制中 STW(Stop-The-World)的时间过长.那么这个时候,我们又会好奇一点,作为 STW 的起始,Go 语言中什么时候才会触发 GC 呢? 1.什么是 GC 在计算机科学中,垃圾回收(GC)是一种自动管理内存的机制,垃圾回收器会去尝试回收程序不再使用的对象及其占用的内存. 最

  • 图解Golang的GC垃圾回收算法

    虽然Golang的GC自打一开始,就被人所诟病,但是经过这么多年的发展,Golang的GC已经改善了非常多,变得非常优秀了. 以下是Golang GC算法的里程碑: v1.1 STW v1.3 Mark STW, Sweep 并行 v1.5 三色标记法 v1.8 hybrid write barrier 经典的GC算法有三种: 引用计数(reference counting) . 标记-清扫(mark & sweep) . 复制收集(Copy and Collection) . Golang的G

  • Go语言七篇入门教程五文件及包

    目录 1. 文件处理 1.1 JSON文件 1.1.1 已知JSON结构 1.1.2 未知JSON结构 1.1.3 Encoder & Decoder 1.2 XML文件 1.3 二进制文件 1.4 zip文件 1.4.1 创建zip 1.4.2 读取zip文件 2. 包管理 2.1 包路径 2.2 包声明 如何学习Go 1. 文件处理 1.1 JSON文件 什么是json? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 也是在web开发中的前后

  • Go语言七篇入门教程七GC垃圾回收三色标记

    目录 GC 如何判断一个对象是否可达 三色标记法 原理如下 GC GC全称Garbage Collection 目前主流的垃圾回收算法有两类,分别是追踪式垃圾回收算法(Tracing garbage collection)和引用计数法( Reference counting ). 而三色标记法是属于追踪式垃圾回收算法的一种. 追踪式算法的核心思想是判断一个对象是否可达,因为一旦这个对象不可达就可以立刻被 GC 回收了. 如何判断一个对象是否可达 分为两步: 第一步找出所有的全局变量和当前函数栈里

  • Go语言七篇入门教程三函数方法及接口

    目录 1. 函数 2. 方法 3. 接口 如何学习Go 参考书籍: <go语言程序设计> 1. 函数 每个函数声明都包含一个名字,一个形参列表,一个可选的返回列表以及函数体: func name(parameter-list)(result-list){ body } 形参列表:指定另一组变量的参数名和参数类型,这些局部变量都由调用者提供的提供的实参传递而来的. 返回列表:指定了函数返回值的类型.当函数返回一个未命名的返回值或者没有返回值的时候,返回列表的圆括号可以忽略. func FanOn

  • Go语言七篇入门教程一简介初识

    目录 简介 为什么是Go Go应用 Web Cloud 云 BlockChain 区块链 如何学习Go 其实我自己接触Go语言也还不到一年,20年的10月我才开始学Go的. 我自己也并不是很懂,但是我希望我能帮助到你学习Go语言,我们可以一起学习交流~ Go语言的吉祥物-金花鼠我一直以为是土拨鼠 在某搜索引擎上一搜golang一堆表情包. 简介 Go语言亦叫Golong语言,是由谷歌Goggle公司推出.Go语言的主要开发者有:肯.汤姆逊(Ken Thompson).罗布.派克(Rob Pike

  • Go语言七篇入门教程二程序结构与数据类型

    目录 1. 程序结构 1.1 名称 1.2 声明 1.3 注释 1.4 单双引号 1.5 输出 2. 数据类型 2.1 整型 2.2 浮点型 2.3 复数 2.4 布尔型 2.5 字符串 2.6 常量 2.7 数组 2.8 切片 2.9 map 2.10 结构体 2.11 JSON 3. 流程控制 3.1 条件语句 3.2 选择语句 3.3 循环语句 如何学习Go 1. 程序结构 1.1 名称 如果一个实体名称在函数中声明,它只在函数局部有效.如果声明在函数外,它将对包里面的所有源文件可见. 实

  • .Net的GC垃圾回收原理及实现

    一.先了解下必备的知识前提 内存中的托管与非托管,可简单理解为: 托管:可借助GC从内存中释放的数据对象(以下要描述的内容点) 非托管:必须手工借助Dispose释放资源(实现自IDisposable)的对象 内存中有栈和堆的概念区分,仅简单说明: 栈:先进后出 的特点(这里不再详细阐述) 堆:存放数据对象实例的内存空间(以下要描述的内容点) 二..Net GC的简单描述 GC垃圾回收是对于内存堆的处理过程. 当一个应用程序进程创建时,会为此应用程序在物理内存堆中分配一块虚拟的连续性内存空间,以

  • Lua语言新手简单入门教程

    一.前言 Lua 是一种轻量小巧的脚本语言,用标准 C 语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 可以应用在游戏开发.独立应用脚本.Web 应用脚本.扩展和数据库插件.安全系统等场景. 笔者学习的目的主要是为了能在 Web 应用(Nginx.Redis)中使用到 Lua 脚本. 特点 Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数. Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上

随机推荐