Go是一种垃圾收集语言:
http://golang.org/doc/go_faq.html#garbage_collection
这里说它是一个标记和扫描垃圾收集器,但它没有深入研究细节,并且正在进行更换......但是,这段似乎没有更新,因为Go是释放。
它仍然是标记和扫描?它是保守还是精确?这是世代的吗?
答案 0 :(得分:108)
Go 1.4+垃圾收集器的计划:
在Go 1.1之上进行1.3垃圾收集器更新:
去1.1垃圾收集器:
去1.0垃圾收集器:
用不同的GC替换GC是有争议的,例如:
答案 1 :(得分:30)
(对于Go 1.8 - Q1 2017, see below)
下一个Go 1.5 并发垃圾收集器涉及能够"节奏" gc。
这是一个提交in this paper的提案,它可能适用于Go 1.5,但也有助于理解Go中的gc。
您可以在 1.5(停止世界:STW)之前看到状态
在Go 1.5之前,Go使用了并行停止世界(STW)收集器。
虽然STW集合有许多缺点,但它至少具有可预测和可控的堆增长行为。
(照片来自GopherCon 2015演示" Go GC: Solving the Latency Problem in Go 1.5")
STW收集器的唯一调整旋钮是“GOGC”,即集合之间的相对堆增长。每次堆大小超过上一个集合的实时堆大小时,默认设置100%都会触发垃圾回收:
STW收集器中的GC定时。
Go 1.5引入了并发收集器 这比STW集合有许多优点,但是由于应用程序可以在垃圾收集器运行时分配内存,因此很难控制堆增长。
(照片来自GopherCon 2015演示" Go GC: Solving the Latency Problem in Go 1.5")
为了实现相同的堆增长限制,运行时必须更早地开始垃圾收集,但是早期多少取决于许多变量,其中许多变量无法预测。
- 过早启动收集器,应用程序将执行太多垃圾收集,浪费CPU资源。
- 启动收集器太晚了,应用程序将超过所需的最大堆增长。
在不牺牲并发性的情况下实现正确的平衡需要仔细调整垃圾收集器。
GC调整旨在沿两个方面进行优化:堆增长和垃圾收集器使用的CPU。
GC起搏的设计包括四个部分:
- GC循环所需扫描工作量的估算器,
- 一种机制,供mutator在堆分配达到堆目标时执行估计的扫描工作量,
- 当mutator协助未充分利用CPU预算时进行后台扫描的调度程序,
- GC触发器的比例控制器。
醇>设计平衡两种不同的时间视图:CPU时间和堆时间。
- CPU时间与标准挂钟时间相似,但速度提高
GOMAXPROCS
倍。
也就是说,如果GOMAXPROCS
为8,那么每隔一秒钟就会有8个CPU秒通过,而每秒一秒,GC会获得2秒的CPU时间。
CPU调度程序管理CPU时间。- 堆时间的通过以字节为单位,并在mutators分配时向前移动。
堆积时间和停留时间之间的关系取决于分配率,并且可以不断变化 Mutator协助管理堆时间的流逝,确保在堆达到目标大小时已完成估计的扫描工作。
最后,触发器控制器创建一个反馈循环,将这两个时间视图绑定在一起,优化堆时间和CPU时间目标。
答案 2 :(得分:17)
这是GC的实施:
https://github.com/golang/go/blob/master/src/runtime/mgc.go
来自资料来源:
GC与mutator线程同时运行,类型准确(也就是精确),允许多个GC线程并行运行。它是一个使用写屏障的并发标记和扫描。它是非代数和非紧凑的。使用按P分配区域隔离的大小来完成分配,以最小化碎片,同时在常见情况下消除锁定。
答案 3 :(得分:8)
Go 1.8 GC可能会再次发展,proposal "Eliminate STW stack re-scanning"
从Go 1.7开始,无限且可能非平凡的停止世界(STW)时间的剩余来源是堆栈重新扫描。
我们建议通过切换到结合Yuasa-style deletion write barrier [Yuasa '90]和Dijkstra-style insertion write barrier [Dijkstra '78]的混合写屏障来消除堆栈重新扫描的需要。
初步实验表明,这可以将最坏情况STW时间减少到50μs以下,这种方法可以使STW标记终止完全消除。
announcement is here您可以看到相关的来源提交是d70b0fe及更早。
答案 4 :(得分:2)
我不确定,但我认为当前(提示)GC已经是并行的,或者至少它是一个WIP。因此,世界各地的财产在不久的将来不再适用或不适用。也许其他人可以更详细地澄清这一点。