gc整体过程
Go 语言的垃圾回收(Garbage Collection, GC)采用了基于三色标记-清除(tri-color mark-and-sweep)算法的并发垃圾回收器。Go 的 GC 在设计上追求低延迟(Low Latency)和高吞吐量(High Throughput),其实现包括标记阶段、清除阶段和与程序运行的协调。下面是 Go GC 的主要实现机制:
# 1. 三色标记-清除算法
三色标记-清除算法将对象分为三种颜色:
- 白色:未访问的对象,GC 开始时所有对象都被标记为白色。
- 灰色:已访问但其引用的对象未被检查的对象。
- 黑色:已访问且其引用的对象都已被检查的对象。
标记阶段:
- GC 从根对象(全局变量、栈上的变量等)开始,将所有直接可达的对象标记为灰色。
- 逐步处理灰色对象,将其引用的对象标记为灰色,并将自己标记为黑色。
- 当没有灰色对象时,标记阶段结束,白色的对象即为不可达对象。
清除阶段:
- 清除所有仍然是白色的对象,回收它们占用的内存。
# 2. 并发垃圾回收
Go 的垃圾回收是并发的,这意味着 GC 可以在程序运行时与用户代码(mutator)并发执行。通过这种方式,Go 减少了 GC 导致的停顿时间。GC 的并发部分包括:
- 并发标记:GC 标记阶段的大部分工作与用户代码并发进行。Go 会启动多个 goroutine 来执行标记操作,这样可以充分利用多核 CPU 的性能。
- STW(Stop-The-World):GC 在标记阶段的开始和结束会进行短暂的 STW 暂停,确保根对象一致性,以及清理阶段的安全性。
# 3. 写屏障(Write Barrier)
写屏障是保证垃圾回收和程序并发执行时一致性的关键技术。在标记阶段,当用户代码(mutator)执行内存写操作时,写屏障会触发相应的逻辑,确保垃圾回收器能够正确地跟踪新创建的引用。这使得在并发标记过程中,标记的信息能够保持准确。
具体来说,写屏障的作用是确保:
- 如果将一个对象引用从一个已标记的对象(黑色)转移到未标记的对象(白色),那么白色对象会立即被标记为灰色,防止它被误认为是不可达的对象。
# 4. 增量标记
Go 的 GC 在标记阶段采用了增量标记技术。这种技术允许 GC 和 mutator 交替执行标记操作,而不需要长时间暂停程序。这进一步降低了 STW 时间,提高了程序的响应性。
# 5. 后台清除
清除阶段大部分工作是在后台完成的,这意味着 GC 会利用空闲时间进行内存回收操作。当程序内存压力较低时,清除阶段可以慢慢进行,而在内存需求较大时,清除阶段会加快执行。
# 6. 动态调节
Go 的 GC 动态调整垃圾回收的频率和堆增长因子,以在低暂停时间和高内存利用率之间取得平衡。GOGC
环境变量允许用户调整 GC 的灵敏度。默认情况下,GOGC
的值是 100,表示当堆增长 100% 时触发 GC。调整 GOGC
的值可以影响 GC 的触发频率和性能表现。
# 7. 协同工作机制
Go 的 GC 与调度器协同工作,以确保 GC 线程与 goroutine 调度之间的平衡,避免垃圾回收占用过多的 CPU 资源,影响程序的正常运行。
# 总结
Go 的垃圾回收器通过三色标记-清除算法、并发标记、写屏障和增量标记等技术,实现了高效的内存管理.