教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 go gc原理

go gc原理

发布时间:2022-01-29   编辑:jiaochengji.com
教程集为您提供go gc原理等资源,欢迎您收藏本站,我们将为您提供最新的go gc原理资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg>

关于 Golang GC 和内存管理相关的流程和原理的一些总结。

<h2>GC 流程</h2>

golang GC 采用基于标记-清除的三色标记法,下图为 golang 一轮完整的 GC 的过程:

一轮完整的 GC,总是从 Off,如果不是 Off 状态,则代表上一轮GC还未完成,如果这时修改指针的值,是直接修改的。

Stack scan: 收集根对象(全局变量和 goroutine 栈上的变量),该阶段会开启写屏障(Write Barrier)。

Mark: 标记对象,直到标记完所有根对象和根对象可达对象。此时写屏障会记录所有指针的更改(通过 mutator)。

Mark Termination: 重新扫描部分全局变量和发生更改的栈变量,完成标记,该阶段会STW(Stop The World),也是 gc 时造成 go 程序停顿的主要阶段。

Sweep: 并发的清除未标记的对象。

<h2>
三色标记</h2>

以上 Mark 阶段,采用的是三色标记法,是传统标记-清除算法的一种优化,主要思想是增加了一种中间状态,即灰色对象,以减少 STW 时间。
三色标记将对象分为黑色、白色、灰色三种:

黑色:已标记的对象,表示对象是根对象可达的。
白色:未标记对象,gc开始时所有对象为白色,当gc结束时,如果仍为白色,说明对象不可达,在 sweep 阶段会被清除。
灰色:被黑色对象引用到的对象,但其引用的自对象还未被扫描,灰色为标记过程的中间状态,当灰色对象全部被标记完成代表本次标记阶段结束。
三色标记的主要过程即:

开始时所有对象为白色
将所有根对象标记为灰色,放入队列
遍历灰色对象,将其标记为黑色,并将他们引用的对象标记为灰色,放入队列
重复步骤 3 持续遍历灰色对象,直至队列为空
此时只剩下黑色对象和白色对象,白色对象即为下一步需要清除的对象

<h2>
STW</h2>

传统的标记-清除算法,为了防止在标记过程中,对象引用发生变化,导致清除仍在使用的对象,需要 STW(Stop The World),这会造成程序的停顿。在三色标记的过程中,由于引入了灰色对象这一中间状态,标记过程和用户的 golang 代码中可以并发执行,不需要 STW,这极大的减少了应用的停顿时间。
三色标记具体如何避免在标记过程中对象应用的改变呢,这里用到了写屏障(Write Barrier)。

<h2>
写屏障</h2>

在 GC 的流程中,Stack scan 这一步骤,启用了写屏障。写屏障的主要思想,是在标记的过程中,通过写屏障记录发生变化的指针,然后在 Mark termination 的 rescan 过程中,重新进行扫描,因为在这一步骤会 STW,所以在这一步骤完成后的白色对象,不会再被引用,可以直接清除。关于写屏障具体原理和实现,这里不再展开。

<h2>
GC触发</h2>

golang 程序的执行过程中,如下几种情况下会触发 GC:

主动触发,用户代码中调用 runtime.GC 会主动触发 GC
默认每 2min 未产生 GC 时,golang 的守护协程 sysmon 会强制触发 GC
当 go 程序分配的内存增长超过阈值时,会触发 GC
内存分配
golang 内存分配分为堆内存和栈内存。
栈:一般函数内部执行中声明的变量,函数返回直接释放,不会引起垃圾回收,对性能无影响。
堆:有引用到的内存空间,靠 GC 回收,会影响程序进程。

<h2>
内存逃逸</h2>

逃逸分析是指由编译器决定内存分配的位置,不需要程序员指定。即由编译器决定新申请的对象会分配到堆上还是栈上。
逃逸分析场景:

<h2>
指针逃逸</h2>

go 将函数内定义的变量返回到函数外,会将本应分配到栈上的内存分配到堆上。
栈空间不足逃逸
当栈空间不足或无法判断当前切片长度时会将对象分配到堆上。
动态类型逃逸
当函数参数为 interface 类型,编译期间无法确定参数的具体类型,也可能会产生逃逸。

<h2>
想一起讨论/学习微信小游戏开发的,GO语言开发的,请微信搜索/或扫码下方小程序加博主微信群</h2>

到此这篇关于“go gc原理”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang GC原理
golang gc实现分析(go1.14.4)
go-内存机制(4)
Golang中的垃圾回收算法
Golang垃圾回收机制
go gc原理
go 垃圾回收:三色算法
golang垃圾回收
golang 释放内存机制的探索
Go 语言内存管理(四):垃圾回收

[关闭]
~ ~