Golang 的GC三色标记法、写屏障的简单理解

Golang 程序运行的时候,内存中的对象可以标记为三色:白色、灰色、黑色。

想象你是一个保洁阿姨(GC),你的任务是把房间里没人要的垃圾扔掉,但最麻烦的是:你干活的时候,屋子里的人(程序)还在不断地扔东西、搬东西。

为了不扔错东西,你准备了三个颜色的塑料袋:


第一步:准备阶段(发袋子)

  1. 白色袋子:屋里所有的东西,默认先全部装进白色袋子(全是潜在垃圾)。
  2. 灰色袋子:你先把那些大家手里正攥着的、桌面上摆着的(根对象:栈、全局变量)东西,换成灰色袋子。

第二步:标记阶段(翻找关联)

这一步最关键,你要开始“顺藤摸瓜”:

  1. 你从灰色袋子里拿出一个东西看一眼。
  2. 如果这个东西关联了其他白色袋里的东西(比如一个本子里夹着一张发票),你就把那张发票也换成灰色袋子。
  3. 等这个东西关联的所有活物都找齐了,你就把手里这个东西换成黑色袋子(表示这玩意儿彻底安全了,检查过了)。

重点来了(写屏障):
在你翻找的时候,如果有人新买了个东西,或者把东西递给了别人,他必须大喊一声:“阿姨,这东西我要用!” 然后你无脑直接给它套个灰色袋子。这样就不会出现“你以为是垃圾,其实人家刚要用”的情况。


第三步:清理阶段(扔垃圾)

等所有的灰色袋子都变成了黑色袋子(说明能找着的活物都找完了),剩下的事儿就简单了:

  • 黑色袋子:全是宝贝,撕掉袋子留着。
  • 白色袋子:全是没人要的垃圾,统统扔进垃圾车!

总结一下这三色:

  • 白色:还没检查到的,或者是检查完了发现没人要的(倒霉蛋)。
  • 灰色:确定要留着,但还没看它下面还牵扯到谁(排队中)。
  • 黑色:确定要留着,而且它引用的东西也都找齐了(安全区)。

为什么不直接“一刀切”暂停程序?

因为如果房子太大,阿姨打扫时让全家人都原地不动(STW),大家会疯掉的(程序卡顿)。

通过这三色袋子和“新买东西必须套灰袋”的规矩,阿姨可以边打扫边让大家活动。虽然中间会短暂让大家停一下手头工作(STW 开启/关闭屏障),但绝大部分时间大家都在各忙各的。

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容