这是我参与「第五届青训营」笔记创作活动的第11天
GO垃圾回收机制
GO垃圾回收与JAVA垃圾回收
非移动GC
非移动垃圾收集器不会重新定位堆中的对象。Go 使用的收集器 CMS 是非移动的。通常,如果在非移动垃圾回收中重复内存分配和释放,最终会出现堆碎片,从而降低分配性能。但是,当然,这将取决于您如何实现内存分配器。
移动GC
移动垃圾收集器通过将活动对象重新定位到堆的末尾来压缩堆。移动垃圾回收的一个例子是 Copying GC,它用在 HotSpot VM 上。
为什么 Go 没有选择压缩
Google 的 Rick Hudson 在国际内存管理研讨会 (ISMM) 的主题演讲Getting To Go中分享了以下内容。
- 2014年,他们本来打算做一个read barrier free concurrent copying GC。
- 由于时间不够——他们正在将用 C 编写的运行时重写为 Go(更改运行时)——他们决定选择 CMS。
- 他们采用了基于 TCMalloc 的内存分配器,解决了碎片化问题并优化了分配。
分代GC
分代 GC 的目的是通过将堆中的对象除以其年龄(它们从 GC 中幸存的次数)来优化 GC,从而分代。世代假说指出,在许多应用中,新对象大多在年轻时就死去。以下基于假设的策略优化了 GC,因为我们可以消除多次扫描旧对象的需要。
- 更频繁地从年轻空间收集垃圾 (Minor GC)。
- 通过将它们重新定位到垃圾收集频率较低的空间(Major GC),提升空间中已在多个 GC 周期中幸存下来的旧对象。
Java8 HotSpot VM 的所有收集器都实现了分代 GC。