Go gc屏障

golang gc:三色标记法,1.5版本开始(采用插入写屏障)

三色:黑白灰

过程:

1.开始所有节点均为白色;

2.扫描所有根节点,标记为灰色;(根节点为编译时确定的全局变量,堆上指针,goroutine栈上指针,扫描过程中新指向堆的指针)

3.扫描灰色节点,找到灰色节点引用的节点,将引用的节点置为灰色,当前灰色节点置为黑色;

4.循环扫描灰色这个过程,(分层,每次一层递归),直到灰色节点为空;

5.三色标记法,gc过程是和业务代码并行执行,业务代码会产生新的指针指向变动,会产生新的堆指针分配,1.5版本采用了插入写屏障,(栈空间分配频繁,不对栈空间进行屏障,需要对栈空间进行stw保护,之后再次rescan栈空间),需要rescan,需要stw;

6.回收白色节点;

写屏障:并发gc会产生黑色节点引用白色节点情况,导致正常的指针变量错误的被清除;解决方法为写屏障;

主要包括强三色不变式和弱三色不变式;

强三色不变:黑色节点不能引用白色节点,如果引用白色节点需要将白色节点置灰(插入写屏障);

弱三色不变:黑节点可以引用白节点,但白节点有其他灰色节点或递归指向存在灰色节点,删除白色节点引用时,需要把白色节点置灰(删除写屏障);

栈上变量较小,且频繁开辟或删除,不开启写屏障;需要之后一次rescan;

stw时机:

        插入写屏障:结束时需要STW来重新扫描栈,标记栈上引用的白色对象的存活;(1.5版本采用)

        删除写屏障:回收精度低,GC开始时STW扫描堆栈来记录初始快照,这个过程会保护开始时刻的所有存活对象;

混合写屏障:1.8版本加入

原因是stw需要耗时;加入混合写屏障,解决这个问题;

流程:

1.开始标记时候,栈上可达节点均置黑,之后不进行rescan,不用stw;

2.gc时产生的在栈上创建的对象,均置黑;

3.堆空间删除的对象置灰;

4.堆空间插入的对象置灰;

异步抢占:1.14加入

之前基于栈增长,一个goroutine如果为for{}空循环,将不会stw,异步抢占后可以抢占当前gotoutine,优化了gc;

理解有限~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值