go的垃圾回收机制

GC触发条件

两个条件满足任一会触发gc:

  • 内存大小达到阈值, 默认是达到上次gc后的2倍
  • 达到规定时间 ,默认2min

解释:
阈值是由一个gc percent的变量控制的,当新分配的内存占已在使用中的内存的比例超过gcprecent时就会触发。比如一次回收完毕后,内存的使用量为5M,那么下次回收的时机则是内存分配达到10M的时候。

也就是说,并不是内存分配越多,垃圾回收频率越高。

如果一直达不到内存大小的阈值呢?这个时候GC就会被定时时间触发,比如一直达不到10M,那就定时(默认2min触发一次)触发一次GC保证资源的回收。

Go1.3的gc

使用的是标记-清除法,分下面四步进行

  • 进行STW(stop the worl即暂停程序业务逻辑)
  • 开始标记,找出可达内存占用并做标记
  • 标记结束,清除未标记的内存占用
  • 结束STW,让程序继续运行,循环该过程直到main生命周期结束

算法评价:
STW会暂停用户逻辑对程序的性能影响是非常大的,这种粒度的STW对于性能较高的程序还是无法接受,因此Go1.5采用了三色标记法优化了STW。

Go1.5gc

Go1.5开始使用的垃圾回收机制是:三色标记法+写屏障+辅助GC

通过以上三种技术,实现了gc线程和用户线程并发执行,而不再是必须stw才能gc,以此减少stw对gc性能的影响。

下面具体看下是怎么做到的

三色标记法

三色标记法可以理解为是标记-清除法的一种增强版本。

三色标记算法将程序中的对象分成白色、黑色和灰色三类。

  • 白色对象表示暂无对象引用的潜在垃圾,其内存可能会被垃圾收集器回收;
  • 灰色对象表示活跃的对象,黑色到白色的中间状态
  • 黑色对象表示活跃的对象,包括不存在引用外部指针的对象以及从根对象可达的对象。

举例:
在这里插入图片描述
三色标记法分五步进行:

  • 将所有对象标记为白色
  • 从根节点集合出发,将第一次遍历到的节点标记为灰色放入集合列表中
  • 遍历灰色集合,将灰色节点遍历到的白色节点标记为灰色,并把灰色节点标记为黑色
  • 循环这个过程
  • 直到灰色节点集合为空,回收所有的白色节点

GC流程

1、Mark
包含两部分:

  • Mark Prepare: 初始化GC任务,包括开启写屏障(write barrier)和辅助GC(mutator assist),统计root对象的任务数量等。这个过程需要STW
  • GC Drains: 扫描所有root对象,包括全局指针和goroutine(G)栈上的指针(扫描对应G栈时需停止该G),将其加入标记队列(灰色队列),并循环处理灰色队列的对象,直到灰色队列为空。该过程后台并行执行

2、Mark Termination:
完成标记工作,重新扫描(re-scan)全局指针和栈。因为Mark和用户程序是并行的,所以在Mark过程中可能会有新的对象分配和指针赋值,这个时候就需要通过写屏障(write barrier)记录下来,re-scan 再检查一下。这个过程也是会STW的。

3、Sweep:
按照标记结果回收所有的白色对象,该过程后台并行执行

4、Sweep Termination:
对未清扫的span进行清扫, 只有上一轮的GC的清扫工作完成才可以开始新一轮的GC。

写屏障(Write Barrier)

写屏障保障了代码描述中对内存的操作顺序, 既不会在编译期被编译器进行调整,也不会在运行时被 CPU 的乱序执行所打乱,

辅助GC

从上面的GC工作的完整流程可以看出Golang GC实际上把单次暂停时间分散掉了,
本来程序执行可能是:⽤户代码–>⼤段GC–>⽤户代码
分散以后实际上变成了:⽤户代码–>⼩段 GC–>⽤户代码–>⼩段GC–>⽤户代码

如果GC回收的速度跟不上用户代码分配对象的速度呢?
当扫描后回收的速度跟不上分配的速度时,go的垃圾回收器依然会stw,⽤户逻辑暂停了以后也就意味着不会有新的对象出现,同时会把⽤户线程抢过来加⼊到垃圾回收⾥⾯加快垃圾回收的速度。使得gc的速度跟上对象分配的速度,作为一种辅助手段帮助更好的gc,所以叫做辅助gc。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值