use*_*432 107 garbage-collection go
Go是一种垃圾收集语言:
http://golang.org/doc/go_faq.html#garbage_collection
在这里它说它是一个标记和清除垃圾收集器,但它没有深入研究细节,并且正在进行替换......但是,自Go发布以来,这段似乎没有更新.
它仍然是标记和扫描?它是保守还是精确?这是世代的吗?
小智 113
Go 1.4+垃圾收集器的计划:
在Go 1.1之上去1.3垃圾收集器更新:
去1.1垃圾收集器:
去1.0垃圾收集器:
用不同的GC替换GC是有争议的,例如:
Von*_*onC 32
下一个Go 1.5 并发垃圾收集器涉及能够"调整"所述gc.
以下是本文中提出的可能适用于Go 1.5 的提议,但也有助于理解Go中的gc.
你可以看到1.5 之前的状态(停止世界:STW)
在Go 1.5之前,Go使用了一个并行的stop-the-world(STW)收集器.
虽然STW集合有许多缺点,但它至少具有可预测和可控的堆增长行为.
(图片来自GopherCon 2015演讲" Go GC:解决Go 1.5中的延迟问题 ")
STW收集器的唯一调整旋钮是"GOGC",即集合之间的相对堆增长.每次堆大小超过上一个集合的实时堆大小时,默认设置100%都会触发垃圾回收:
STW收集器中的GC定时.
Go 1.5引入了一个并发收集器.
这比STW集合有许多优点,但它使堆增长更难控制,因为应用程序可以在垃圾收集器运行时分配内存.
(图片来自GopherCon 2015演讲" Go GC:解决Go 1.5中的延迟问题 ")
为了实现相同的堆增长限制,运行时必须更早地开始垃圾收集,但是早期取决于许多变量,其中许多变量无法预测.
- 过早启动收集器,应用程序将执行太多垃圾收集,浪费CPU资源.
- 太晚启动收集器,应用程序将超过所需的最大堆增长.
在不牺牲并发性的情况下实现正确的平衡需要仔细调整垃圾收集器的速度.
GC调整旨在沿两个维度进行优化:堆增长和垃圾收集器使用的CPU.
GC起搏的设计包括四个部分:
- GC循环所需扫描工作量的估算器,
- 一种机制,让mutator在堆分配达到堆目标时执行估计的扫描工作量,
- 当mutator协助未充分利用CPU预算时,用于后台扫描的调度程序,以及
- GC触发器的比例控制器.
该设计平衡了两种不同的时间视图:CPU时间和堆时间.
- CPU时间就像标准挂钟时间,但通过
GOMAXPROCS
时间更快.
也就是说,如果GOMAXPROCS
是8,那么每秒墙就会有8个CPU秒通过,而每秒墙就会有两秒钟的CPU时间.
CPU调度程序管理CPU时间.- 的通过堆时间以字节为单位和向前移动为存取器分配.
堆时间和挂壁时间之间的关系取决于分配率,并且可以不断变化.
Mutator协助管理堆时间的流逝,确保在堆达到目标大小时已完成估计的扫描工作.
最后,触发器控制器创建一个反馈循环,将这两个时间视图绑定在一起,优化堆时间和CPU时间目标.
ber*_*rio 18
这是GC的实现:
https://github.com/golang/go/blob/master/src/runtime/mgc.go
来自源文档:
GC与mutator线程同时运行,类型准确(也称为精确),允许多个GC线程并行运行.它是一个使用写屏障的并发标记和扫描.它是非代数和非紧凑的.使用按P分配区域隔离的大小来完成分配,以最小化碎片,同时消除常见情况下的锁定.
Go 1.8 GC可能会再次发展,提议"消除STW堆栈重新扫描"
从Go 1.7开始,无限制且可能非平凡的世界末日(STW)时间的剩余来源是堆栈重新扫描.
我们建议通过切换到混合写屏障来消除对堆栈重新扫描的需要,该屏障结合了Yuasa风格的删除写屏障[Yuasa '90]和Dijkstra风格的插入写屏障[Dijkstra '78].
初步实验表明,这可以将最坏情况的STW时间减少到50μs以下,并且这种方法可以使得完全消除STW标记终止变得切实可行.
该公告是在这里,你可以看到相关的源提交是d70b0fe和更早版本.