40

Golang的垃圾回收(GC)机制

 5 years ago
source link: https://studygolang.com/articles/15300?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

转载自 https://blog.csdn.net/liangzhiyang/article/details/52670021

请先阅读   golang goroutine 调度机制 然后再到这里

golang 的垃圾回收 采用的是   标记 - 清理( Mark-and-Sweep   算法

就是先标记出需要回收的内存对象快,然后在清理掉;

在这里不介绍 标记和清理的具体策略(可以参考https://lengzzz.com/note/gc-in-golang),只介绍 GC 过程是怎么调度的以及 stw 相关

这个算法,会导致 stw (stop the world) 的问题,中断用户逻辑

触发 GC 机制

1.     在申 内存的 候, 检查 当前当前已分配的内存是否大于上次 GC 后的内存的 2 倍,若是 (主 GC 线程为当前 M

2.     监控线程发现上次 GC 时间 两分 了,触 ;将一个 G 放到全局 G 队列中去。(主 GC 线程为执行这个 G M

每当触发的时候,在主 GC 线程中就会走如下的 GC 流程:

1.     stop the world ,等待所有的 M 休眠;此 所有的 业务逻辑 都停止

2.     标记:分配 gc 标记任务,唤醒 gcproc M (就是第一步休眠的那些),分 个,直到所有的 M 都做完,才 束;并且所有 M 再次 入休眠

3.     清理:有一个 独的 goroutine 去清理已 经标记 的内存 象快

4.     start the world gcwaiting=0 醒所有的 M (不会超 P 个数)

对于上面的三个步骤,分别解释:

stop the world

1.     设置 gcwaiting=1 个在每一个 G 之前会 检查 一次 个状 ,如是, 会将当前 M 休眠;

2.     如果 M 里面正在运行一个 长时间 G ,咋 呢, 道会等待 G 自己切 换吗 这样 可要等 10ms 啊,不能等! 决不能等!
所以会主 动发 标记 似于上一篇), 当前 G 中断,再运行下一个 G 候,就会走到第 1

3.     一直等待所有的 M 进入休眠,此时所有的业务逻辑代码都停

标记:

1.       根据 gcproc 的个数,分配成 gcproc 段; gcproc-1 M 行(当前 M 也算一个

2.     对于一个 M 醒前 设置它的 helpgc 标记,唤醒之后这个 M 会立 判断 标记 ,如是, 开始做分配 自己的 标记 务,如果先做完了,就会从别的 M 里面找一些来做

3.     等每一个 M 都做完,会再次 入休眠

清理:

1.     过设 置参数,可以以一个 goroutine   运行, 个功能是在 1.3 版本之后增加的, 这样 就直接到下一步了,清理 程不是 stw

2.     也可以串行的在主 GC 线程执行;这样的话则 清理 程也是 stw 的,

start the world

1.     设置 gcwaiting=0

2.     唤醒 P M 继续 G (此 没有 helpgc 标记),业务逻辑代码开

综上:

是基于 1.4 版本的, GC 过程在 标记过程是( STW )的

1.5 版本里面对 GC 做了很大的优化;采用三色标记,将标记过程细化成三段,只有前后的两段是 stw 的;极大地缩短了 gc stw 时间

Center


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK