1.GC
GC 在 Go 语言中代表垃圾收集(Garbage Collection)。
它是 Go 运行时(runtime)的一部分,负责自动管理内存的分配和释放。当程序中的变量或对象不再被需要时,GC 会自动回收这些不再使用的内存空间,使其可以被重新分配给其他变量或对象。
Go 的垃圾收集器是并发的,并且是非阻塞的,这意味着它在后台运行,尽量减少对程序执行的干扰。Go 的 GC 设计目标是减少延迟,即尽量避免因为垃圾收集而导致的程序暂停时间过长。
Go 的垃圾收集器主要有以下特点:
- 并发执行:GC 大部分工作是与程序的主要执行流并发进行的,减少了程序的停顿时间。
- 三色标记清除算法:Go 使用改进的三色标记清除算法进行垃圾收集,通过标记阶段确定哪些对象是可达的(即仍然被需要的),然后清除那些不可达的对象。
- 写屏障(Write Barrier):在标记阶段,为了保证并发执行的正确性,Go 使用写屏障技术来处理程序对内存的写操作,确保垃圾收集的准确性。
- STW(Stop-The-World):虽然 Go 的 GC 尽量减少对程序执行的影响,但在某些阶段(如标记开始和标记结束阶段)仍然需要短暂地停止程序中的所有 Goroutine,这被称为 STW 停顿。Go 的设计者不断努力减少这种停顿的时间。
通过自动管理内存,GC 使得 Go 程序员可以更加专注于业务逻辑的实现,而不需要手动管理内存的分配和释放,从而减少了内存泄漏和其他内存相关错误的可能性。
2.GC的触发场景
GC触发方式包括:自动和手动两种。
其中,手动是用户主动调用runtime.GC()
.
自动方式分两种:
- 达到设定的阈值时自动触发
- 周期执行
在go的runtime代码中,可以看到:
const (
// gcTriggerHeap indicates that a cycle should be started when
// the heap size reaches the trigger heap size computed by the
// controller.
gcTriggerHeap gcTriggerKind = iota
// gcTriggerTime indicates that a cycle should be started when
// it's been more than forcegcperiod nanoseconds since the
// previous GC cycle.
gcTriggerTime
// gcTriggerCycle indicates that a cycle should be started if
// we have not yet started cycle number gcTrigger.n (relative
// to work.cycles).
gcTriggerCycle
)
其中,
gcTriggerHeap
是阈值触发方式。
gcTriggerTime
是周期触发的方式,周期默认是2分钟:
var forcegcperiod int64 = 2 * 60 * 1e9
gcTriggerCycle
实际表示的用户触发的方式:
// For stats, check if this GC was forced by the user.
work.userForced = trigger.kind == gcTriggerCycle