请简单描述 Go 语言 GC(垃圾回收)的工作原理

请尝试在评论区里写下答案(如不能清楚表述,那么你可能没真正理解)。欢迎参与,为下一次求职做准备。

请在评论区留下你的答案

摈弃世俗浮躁,追求技术精湛
本帖已被设为精华帖!
本帖由系统于 2天前 自动加精
Summer
讨论数量: 3

之前做过一些简短的总结

三色标记,黑白灰三色,初始都是白色

  • 白色,对象未被标记
  • 黑色,对象已被标记,且子对象均被标记
  • 灰色,对象已被标记,但对象包含的子对象未标记

根据顺序,先进行根对象分析,将白色对象转为灰色,然后进行灰色分析,如果不存在引用子对象(白色),转为黑色,如果存在引用子对象,那么引用子对象变成灰色,被分析的灰色对象变为黑色,再继续灰色分析,直到不存在灰色,就将白色删除,黑色保留。

触发条件:

  • 默认是内存扩大一倍
  • 2min 定时触发
  • 手动执行 runtime.gc()

GC 过程会通过写屏障实现并发,但在标记开始和结束时还是会有 STW

2周前 评论

之前做过一些简短的总结

三色标记,黑白灰三色,初始都是白色

  • 白色,对象未被标记
  • 黑色,对象已被标记,且子对象均被标记
  • 灰色,对象已被标记,但对象包含的子对象未标记

根据顺序,先进行根对象分析,将白色对象转为灰色,然后进行灰色分析,如果不存在引用子对象(白色),转为黑色,如果存在引用子对象,那么引用子对象变成灰色,被分析的灰色对象变为黑色,再继续灰色分析,直到不存在灰色,就将白色删除,黑色保留。

触发条件:

  • 默认是内存扩大一倍
  • 2min 定时触发
  • 手动执行 runtime.gc()

GC 过程会通过写屏障实现并发,但在标记开始和结束时还是会有 STW

2周前 评论

我也说下我梳理的

Go的GC用了三色标记法、屏障技术、增量与并发实现的。

三色标记法

三色标记法的颜色

三色标记法分白色、灰色、黑色
● 白色 —– 潜在的垃圾(注意是潜在)
● 灰色 —- 活跃的对象
● 黑色 —- 活跃的对象

三色标记法的过程

三色标记法的过程是:

  • 从灰色队列里取出灰色对象,并把它标记成黑色。
  • 把黑色对象所引入的外部对象标记成灰色(本来就是灰的保持原状)。
  • 重复上述操作直至灰色队列为空,标记结束。

屏障技术

屏障技术是为了保证屏障前的操作优于屏障后的操作。主要是保证顺序性的。

屏障技术相当于是钩子函数,它是在用户程序读取对象、更新对象、创建对象指针时执行的一段代码,故又分为读屏障和写屏障。由于在读操作远远高于写操作所以为了性能,都是以写屏障来保证三色不变性。
Go在1.8版本的时候结合了写屏障和删除写屏障。该写屏障会将被覆盖的对象标记成灰色并在当前栈没有扫描时将新对象也标记成灰色。

注意 混合屏障技术是在go 1.8版本才引入的,就是结合了写屏障和删除写屏障,目的是将被覆盖的对象标记成灰色并在当前栈没有扫描时将新对象也标记成灰色。

增量与并发

此技术的出现为了解决暂停时间过长的手段。由于垃圾收集器在执行阶段会暂停应用程序,但是很多实时的应用程序是无法接受长时间的暂停的,这两个技术也就应运而生。

增量收集器

增量收集器为了降低程序最长暂停时间的一种方案,这个方案也是非常直接,直接把这个较长的暂停时间,切分成多个小的GC时间片。在整体来看增加了总的暂停时间,但是确实是降低了最长暂停时间。

并发收集器

并发收集器不仅可以降低最长暂停时间而且还可以降低垃圾收集阶段的暂停时间。

最长暂停时间是指,垃圾收集器一个任务执行的最长时间
总的暂停时间是指,垃圾收集器从开始暂停到结束的时间。

通过开启屏障、利用多核优势与用户程序并行执行。由于是要开启屏障,又与用户程序一起执行,所以会有额外开销,而且会增加总的暂停时间,还会影响用户程序。

Go的版本之间差异是有的所以面试的时候一定要注意版本。

1周前 评论
playmaker

黑白灰 标记 回收白色垃圾

1周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!