Go的垃圾回收

V1.3

标记清除+STW,这个比较好理解,就不详细阐述了。

V1.5

提出了三色标记法,伴随有STW
新生的对象都会标记成白色,然后从根节点出发一次遍历,将遍历过的对象标记成灰色的,并且全局变量和栈中的对象置灰色。
最后将灰色对象标记为黑色,直到没有灰色对象全部转换成黑色对象为止。将所有的白色对象全部回收。

假设没有STW,在标记过程中很有可能出现引用关系的改变。一旦改变了这个关系(尤其是黑色对象直接指向白色对象),就会出现“误删除”的操作。
上述情况只针对于下面两个条件:

  1. 一个白色对象被黑色对象引用(白色被挂在黑色下)
  2. 灰色对象与它之间的可达关系的白色对象遭到破坏(灰色同时丢了该白色) 如果当以上两个条件同时满足时,就会出现对象丢失现象!

STW也暴露出很大的性能瓶颈问题,针对上述问题提出了相应的解决方案。

引入了屏障机制

  1. 强三色不变式 不允许黑色对象引用白色对象
  2. 弱三色不变式 白色对象存在灰色对象的引用,或者可达它的链路的上游存在灰色对象,黑色对象就可以引用白色对象

插入屏障
在堆上的黑色对象引用白色对象时,需要把白色对象标记成灰色对象,满足强三色不变式
栈上的对象会在STW 的保护下重新进行标记

删除屏障
被删除的对象,本身如果是灰色或者白色都会标记成灰色对象
满足弱三色不变式

V1.8

针对插入写屏障和删除写屏障的短板:

● 插入写屏障:结束时需要STW来重新扫描栈,标记栈上引用的白色对象的存活;
● 删除写屏障:回收精度低,GC开始时STW扫描堆栈来记录初始快照,这个过程会保护开始时刻的所有存活对象。

于是引入了混合写屏障 ,避免了对栈的re-scan操作,极大地减少了STW的时间。
具体操作:

1、GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW),

2、GC期间,任何在栈上创建的新对象,均为黑色。

3、被删除的对象标记为灰色。

4、被添加的对象标记为灰色。

以上就是对Golang垃圾回收机制中的三色标记的详细描述,希望同学们批评指正。

### Golang 垃圾回收机制详解 #### 标记-清除过程中的STW现象 在垃圾回收的过程中,有部分操作是必须要停止所有的用户线程,这被称为STW(Stop The World)。对于Golang而言,在早期版本中,由于垃圾回收采用的是串行的方式,因此STW的时间特别长,甚至能达到数百毫秒[^1]。 随着版本迭代至Golang 1.8之后,通过系列优化措施,使得STW停顿时间显著降低到小于1毫秒。这成就标志着Go语言团队成功解决了长时间暂停的问题,极大提升了应用程序性能和用户体验。 #### GC算法的发展历程 自诞生以来,Go语言的GC算法经历了多个重要发展阶段: - **v1.3之前**:此时的垃圾回收完全依赖于STW完成整个流程,即每次执行标记与清理工作期间都需要冻结所有应用进程。 - 后续版本逐步引入了更先进的技术手段,比如并行处理能力以及减少全局同步需求等策略,从而有效缩短了因垃圾收集造成的中断时长[^2]。 #### 当前实现方式概述 当前,Golang垃圾回收主要由两个核心阶段构成——标记和清除。这两个步骤不再像过去那样全部需要STW支持;相反,大部分工作可以在后台持续进行而不影响主线程正常运作。具体来说: - **标记阶段**:识别出哪些对象仍然处于活跃状态,并对其进行标注以便后续处理; - **清除阶段**:负责释放那些已经被确认为无用的对象所占用的空间资源[^4]。 此外,为了进步提高效率,还采用了诸如屏障(Write Barrier)这样的高级特性来辅助管理指针变化情况下的数据致性问题[^3]。 ```go // 示例代码展示如何触发垃圾回收 runtime.GC() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hewesH

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

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

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

打赏作者

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

抵扣说明:

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

余额充值