Go三色标记清除是分阶段并发GC,通过写屏障保障强三色不变式,STW仅限根扫描与栈重扫,清除异步按页进行,延迟压至百微秒级。
Go 的三色标记清除(Tri-color Marking + Sweep)不是一次性停顿扫描,而是一个分阶段、带写屏障保护的并发回收流程。它核心目标是把 STW(Stop-The-World)压缩到毫秒级,同时不丢对象、不误回收。
三色状态的本质含义
所谓“三色”,是逻辑抽象,并非真实存储颜色值:
白色
:初始默认状态,表示“尚未确认是否可达”;GC 结束后仍为白色的对象即为垃圾,会被清除
灰色
:已确认可达,但其引用的对象还没被扫描;它们被存放在一个标记队列(gcWork)中,等待处理
黑色
:已完全扫描完毕,该对象及其所有直接/间接引用都已纳入标记范围;本次 GC 中不会被回收
标记阶段的四步主流程
标记不是全堆扫一遍,而是从根集合出发,逐步推进灰色边界,直到灰色队列清空:
将所有根对象(全局变量、各 goroutine 栈上指针、寄存器等)标记为灰色,并入队
从队列取一个灰色对象,扫描它持有的所有指针字段
对每个指针指向的白色对象,将其标记为灰色并入队
当前对象自身标记为黑色;重复直到队列为空
此时所有可达对象非黑即灰(灰是过渡态),白色对象即为不可达垃圾。
为什么需要写屏障?防止对象丢失
因为标记和用户代码并发执行,若不加干预,可能出现“黑色对象引用新创建的白色对象”,而该白色对象又无其他灰色路径可达——它就会被漏掉、误回收。这就是违反
强三色不变式
。
Android 操作系统的介绍 中文WORD版
本文档主要讲述的是Android 操作系统的介绍;Android是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统,早期由Google开发,后由开放手持设备联盟(Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。底层Linux内核只提供基本功能;其他的应用软件则由各公司自行开发,部分程序以Java编写。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
Go 自 1.8 起采用
混合写屏障(hybrid write barrier)
,在指针赋值时插入检查逻辑:
当发生
,且 A 已是黑色、B 是白色时,强制将 B 标记为灰色
该机制覆盖堆上写操作,配合最后的 STW 栈重扫描,确保栈上新产生的指针也被捕获
清除阶段如何做到几乎无停顿
清除不再像早期那样遍历整个堆,而是按页(page)异步清理:
标记结束后,白色对象的内存页被标记为“可回收”,但不立即归还 OS
后续内存分配时,优先复用这些页;真正释放给
操作系统
由后台线程按需完成
Go 1.19 引入软内存限制(
),让清除更主动响应内存压力
因此,清除本身基本不造成用户可观测延迟,真正的 STW 只发生在标记开始前的根扫描准备,以及标记结束后的栈重扫描,通常控制在百微秒级。
A.field = BGOMEMLIMIT