在 Go 中,使用的垃圾回收(GC)策略是 Concurrent Mark-Sweep(CMS)。这是一种基于分代的、并发的、并行的垃圾回收器,设计上考虑到了低延迟、高吞吐量和尽可能小的暂停时间。
Go 的 GC 由两个主要阶段组成:标记(Mark)阶段和清扫(Sweep)阶段。
在 Go 中,垃圾回收器还使用了一种叫做“分代回收”(Generational GC)的优化技术。简单来说,这种技术的思想是,新创建的对象更有可能在短时间内变得非活动,因此应该更频繁地对它们进行回收。在每次 GC 后,Go 会标记出那些有对象被分配但是没有被清理的内存区域,然后在下一次 GC 时优先对这些区域进行标记和清扫。
触发GC
Go的垃圾回收并不是定时触发的,它的触发时机主要取决于内存的分配情况。Go使用的是一个基于分配的触发机制,而不是基于时间的触发机制。
当你的程序分配的内存超过一定阈值时,垃圾回收器就会触发。这个阈值是由上一次垃圾回收之后的存活对象数量计算出来的。具体来说,如果上次垃圾回收结束后,存活对象占用的内存大小为X,那么当新分配的内存加上X达到2X时,就会触发新的垃圾回收。
换句话说,垃圾回收的触发是基于堆的增长速率的。如果你的程序持续分配新的内存但不释放旧的内存,垃圾回收会更频繁地触发。反之,如果你的程序的内存分配速率较低,或者分配的内存很快就被释放,垃圾回收就不会那么频繁地触发。
需要注意的是,虽然这是Go的默认行为,但是你可以通过调用runtime.GC()
函数来手动触发垃圾回收。此外,你还可以通过调整GOGC
环境变量来改变垃圾回收的触发频率,例如,设置GOGC=200
(这是默认值)表示当堆的大小增长到上次垃圾回收后的两倍时触发垃圾回收,设置GOGC=100
则表示当堆的大小增长到上次垃圾回收后的一倍时触发垃圾回收。