# 8.6 标记终止阶段
## 终止检测算法
### 标记终止阶段的移除
在 Go 1.5 之前, Go 的垃圾回收器是一个全局的垃圾回收器,Go 持续支持 STW 垃圾回收作为调试模式。 Go 1.5 引入了并发收集器,但为了最少限度的减少大规模侵入式更改,它将大部分现有的 GC 机制保留为 STW 的标记终止 (Mark Termination), 同时在 STW 阶段之前添加并发标记阶段。尽管这个并发标记阶段尽可能的实现了理应并发的部分,但最终还是需要 STW 算法来清理它没有实现的工作。
在 Go 1.8 之前,并发标记总是留下至少一部分工作(Dijkstra 写屏障的特点),因为在标记终止期间,必须重新扫描并发阶段期间修改的任何栈。 Go 1.8 引入了一个新的写屏障(即混合写屏障),不再需要对栈进行重新扫描,从而大大减少了标记终止时必须完成的工作量。 然而,由于它之前从未真正的重要,我们对于进入标记终止阶段是相当马虎的:决定何时进入标记终止的算法通常需要等到所有工作都由并发标记完成, 但有时部分工作会一楼,留下标记终止清理混乱。
此外,为了最小化(但不消除)过早进入标记终止的机会,Go 1.5 将并行标记划分为 Mark1 和 Mark2 两个阶段。在 Mark1 期间, 当它用完全局标记工作时,将刷新并禁用所有本地工作缓存(启用立即标黑模式)并输入 Mark2。在 Mark2 期间,当它再次用完全局标记工作时, 它将进入标记终止。不幸的是,立即标黑的模式会对性能造成一定影响(这些本地缓存存在原因),并且算法可以在 GC 周期的早起进入 Mark2, 因为它仅检测工作瓶颈。虽然禁用所有本地缓存旨在防止标记过早终止,但这并不总是有效。
### 使用无竞争算法替换 Mark2
#### 证明
**定理: 当算法终止时,如果所有标记工作队列为空,则终止检测算法会成功。**
- 第一部分 :基础篇
- 第1章 Go语言的前世今生
- 1.2 Go语言综述
- 1.3 顺序进程通讯
- 1.4 Plan9汇编语言
- 第2章 程序生命周期
- 2.1 从go命令谈起
- 2.2 Go程序编译流程
- 2.3 Go 程序启动引导
- 2.4 主Goroutine的生与死
- 第3 章 语言核心
- 3.1 数组.切片与字符串
- 3.2 散列表
- 3.3 函数调用
- 3.4 延迟语句
- 3.5 恐慌与恢复内建函数
- 3.6 通信原语
- 3.7 接口
- 3.8 运行时类型系统
- 3.9 类型别名
- 3.10 进一步阅读的参考文献
- 第4章 错误
- 4.1 问题的演化
- 4.2 错误值检查
- 4.3 错误格式与上下文
- 4.4 错误语义
- 4.5 错误处理的未来
- 4.6 进一步阅读的参考文献
- 第5章 同步模式
- 5.1 共享内存式同步模式
- 5.2 互斥锁
- 5.3 原子操作
- 5.4 条件变量
- 5.5 同步组
- 5.6 缓存池
- 5.7 并发安全散列表
- 5.8 上下文
- 5.9 内存一致模型
- 5.10 进一步阅读的文献参考
- 第二部分 运行时篇
- 第6章 并发调度
- 6.1 随机调度的基本概念
- 6.2 工作窃取式调度
- 6.3 MPG模型与并发调度单
- 6.4 调度循环
- 6.5 线程管理
- 6.6 信号处理机制
- 6.7 执行栈管理
- 6.8 协作与抢占
- 6.9 系统监控
- 6.10 网络轮询器
- 6.11 计时器
- 6.12 非均匀访存下的调度模型
- 6.13 进一步阅读的参考文献
- 第7章 内存分配
- 7.1 设计原则
- 7.2 组件
- 7.3 初始化
- 7.4 大对象分配
- 7.5 小对象分配
- 7.6 微对象分配
- 7.7 页分配器
- 7.8 内存统计
- 第8章 垃圾回收
- 8.1 垃圾回收的基本想法
- 8.2 写屏幕技术
- 8.3 调步模型与强弱触发边界
- 8.4 扫描标记与标记辅助
- 8.5 免清扫式位图技术
- 8.6 前进保障与终止检测
- 8.7 安全点分析
- 8.8 分代假设与代际回收
- 8.9 请求假设与实务制导回收
- 8.10 终结器
- 8.11 过去,现在与未来
- 8.12 垃圾回收统一理论
- 8.13 进一步阅读的参考文献
- 第三部分 工具链篇
- 第9章 代码分析
- 9.1 死锁检测
- 9.2 竞争检测
- 9.3 性能追踪
- 9.4 代码测试
- 9.5 基准测试
- 9.6 运行时统计量
- 9.7 语言服务协议
- 第10章 依赖管理
- 10.1 依赖管理的难点
- 10.2 语义化版本管理
- 10.3 最小版本选择算法
- 10.4 Vgo 与dep之争
- 第12章 泛型
- 12.1 泛型设计的演进
- 12.2 基于合约的泛型
- 12.3 类型检查技术
- 12.4 泛型的未来
- 12.5 进一步阅读的的参考文献
- 第13章 编译技术
- 13.1 词法与文法
- 13.2 中间表示
- 13.3 优化器
- 13.4 指针检查器
- 13.5 逃逸分析
- 13.6 自举
- 13.7 链接器
- 13.8 汇编器
- 13.9 调用规约
- 13.10 cgo与系统调用
- 结束语: Go去向何方?