GC机制

垃圾回收机制

1. Mark & Sweep

两个主要概念:

  • STW: stop the world, GC 的一些阶段需要停止所有的 mutator 以确定当前的引用关系。这便是很多人对 GC 担心的来源,这也是 GC 算法优化的重点。

  • Root: 根对象是 mutator 不需要通过其他对象就可以直接访问到的对象。比如全局对象,栈对象中的数据等。通过Root 对象,可以追踪到其他存活的对象。

在Go1.1版本,Mark-Sweep算法就是严格按照追踪式算法的思路来实现的:

  1. Stop the World
  2. Mark:通过 Root 和 Root 直接间接访问到的对象, 来寻找所有可达的对象,并进行标记。
  3. Sweep:对堆对象迭代,已标记的对象置位标记。所有未标记的对象加入freelist, 可用于再分配。
  4. Start the Wrold,这个算法最大的问题是 GC 执行期间需要把整个程序完全暂停,朴素的 Mark Sweep 是整体 STW,并且分配速度慢,内存碎片率高,GC时间为秒级。

在Go1.3的版本中,标记过程需要 STW,因为对象引用关系如果在标记阶段做了修改,会影响标记结果的正确性。
并发 GC 分为两层含义:

  • 每个 mark 或 sweep 本身是多个线程(协程)执行的(concurrent)
  • mutator 和 collector 同时运行(background)
    concurrent 这一层是比较好实现的, GC 时整体进行STW,那么对象引用关系不会再改变,对 mark 或者sweep 任务进行分块,就能多个线程(协程) conncurrent 执行任务 mark 或 sweep。而对于 backgroud 这一层, 也就是说 mutator 和 mark,sweep 同时运行,则相对复杂。
  • 1.3以前的版本使用标记-清扫的方式,整个过程都需要 STW。
  • 1.3版本分离了标记和清扫的操作,标记过程STW,清扫过程并发执行。
    backgroup sweep 是比较容易实现的,因为 mark 后,哪些对象是存活,哪些是要被 sweep 是已知的,sweep 的是不再引用的对象。sweep 结束前,这些对象不会再被分配到,所以 sweep 和 mutator 运行共存。无论全局还是栈不可能能访问的到这些对象,可以安全清理。

GC机制
https://www.zengzx.xyz/2022/10/27/01.知识架构/01.Go/01.基础/13.GC机制/
作者
Eden
发布于
2022年10月27日
许可协议