【golang】GC垃圾回收机制

GO1.3之前的版本 标记清除法

标记清除:GC流程

  1. 暂停程序业务逻辑,找出当前没有直接应用的对象,和直接引用的对象
  2. 标记直接引用对象
  3. 删除未被标记的对象
  4. 停止暂停,恢复程序运行
  5. 循环往复,知道程序停止
  1. 标记在这里插入图片描述
  2. 删除未标记对象在这里插入图片描述

标记清除:缺点 STW

  1. 产生程序卡顿-STW(程序中断垃圾回收)(解决:先恢复运行,后台清除未标记对象,缩短暂停时间)
  2. 会产生很多堆的碎片

GO1.5的版本 三色标记法

三色标记:GC流程

  1. 创建对象就标记为白色
    在这里插入图片描述

  2. GC回收开始从ROOT SET根节点遍历,把遍历到的对象,从白色集合放到黑色集合中
    在这里插入图片描述

  3. 遍历灰色集合,将灰色集合引用的对象,从白色集合放入黑色集合中。之后将灰色对象放入黑色集合中。
    在这里插入图片描述

  4. 重复第3步骤,直到灰色中没有任何对象。(只有黑色和白色)
    在这里插入图片描述

  5. 回收所有白色对象,GC
    在这里插入图片描述

三色标记:缺点以及优化

产生问题

  1. 白色对象被当前的黑色对象引用
  2. 之前的灰色对象与白色对象之间引用关系结束

如上两个条件同时满足,则白色对象被误删

优化:强弱三色不变式

强弱三色不变式

三色标记只要满足 强/弱三色不变式之一,就可以保证对象不丢失

强三色不变式

在这里插入图片描述

弱三色不变式

黑色对象可以引用白色对象,但是白色必须被灰色对象引用,黑色才可以指向白色在这里插入图片描述

屏障机制

插入屏障

只在堆函数上作用,因为堆中存储的内存占比较大,栈中存储的及时运行程序的内存(方法压栈),保证程序稳定运行,所以只作用的堆上。
三色标记扫描完成后,会STW栈空间,重新扫描(因为栈没有触发写屏障),后完成垃圾回收。

  • 插入规则:对象被引用触发。当插入新节点挂载载上一节点下,新节点被标记为灰色。(伪代码如下)
  • 优势:满足强弱三色不变式(不存在黑色引用白色对象,白色都强制变为灰色
  • 缺点:需要STW,重新扫描堆空间(栈不触发插入写屏障)
func 添加下游对象(当前下游对象ptr, 新的下游对象) {
	// 1
	标记为灰色(新的下游对象)
	// 2
	当前下游对象ptr = 新的下游对象
}

删除屏障

  • 删除规则:被删除对象,自身是黑色或者白色,则被标记为灰色
  • 满足:弱三项不定式(保证后续对象引用不被删除)
func 删除下游对象(当前下游对象, 新下游对象) {
	if 当前下游对象==灰色 || 当前下游对象==白色 {
		标记为灰色(当前下游对象)
	}
	当前下游对象 = 新下游对象
}

// 引用链 A->B->C->D
// 直接删除B,则B变为灰色对象
删除下游对象(A, nil)
// 则A对象旧指针指向的对象变为灰对象,B对象边灰对象
删除下游对象(A, C)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼小鱼啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值