go-GC
在 Go 语言中,GC(Garbage Collection,垃圾回收)是自动管理内存的机制。 Go 语言的垃圾回收器负责在程序运行时自动识别和回收不再使用的内存,以避免内存泄漏和手动内存管理引发的问题。
Go 语言的垃圾回收器使用了标记-清除(mark-and-sweep)算法。
垃圾回收器的工作流程:
标记阶段(Marking Phase):垃圾回收器会从根对象(如全局变量、栈上的变量等)开始,递归地遍历对象图,标记所有可达的对象。
清除阶段(Sweeping Phase):垃圾回收器会扫描堆上的所有对象,并清除那些未被标记的对象,即未被标记的对象被认为是不再使用的,可以回收它们占用的内存。
内存整理(Memory Compaction):为了减少内存碎片化,有些垃圾回收器还会进行内存整理操作。内存整理会将存活的对象向一端移动,以便在另一端形成连续的可用内存空间。
Go 语言的垃圾回收器是并发的,也就是说,在进行垃圾回收的同时,程序的其他部分仍然可以继续执行。这种并发垃圾回收的机制能够减少垃圾回收对程序性能的影响。
由于垃圾回收器是自动进行的,不需要显式地释放对象的内存。不过,对于一些特殊情况,比如需要主动释放资源的情况,Go 语言也提供了 runtime 包中的函数供开发者手动触发垃圾回收或者管理内存。
Go 语言的垃圾回收器是一种自动管理内存的机制,它负责在程序运行时自动回收不再使用的内存,避免了手动内存管理的复杂性,并提供了并发执行的能力,以减少对程序性能的影响。
go GC 触发时机
主动触发:调用 runtime.GC
被动触发:
使用系统监控,该触发条件由 runtime.forcegcperiod 变量控制,默认为 2 分 钟。当超过两分钟没有产生任何 GC 时,强制触发 GC。
使用步调(Pacing)算法,其核心思想是控制内存增长的比例。如 Go 的 GC 是一种比例 GC, 下一次 GC 结束时的堆大小和上一次 GC 存活堆大小成比例
GC 的流程
Go1.14 版本以 STW 为界限,可以将 GC 划分为五个阶段:
GCMark 标记准备阶段,为并发标记做准备工作,启动写屏障
STWGCMark 扫描标记阶段,与赋值器并发执行,写屏障开启并发
GCMarkTermination 标记终止阶段,保证一个周期内标记任务完成,停止写屏 障
GCoff 内存清扫阶段,将需要回收的内存归还到堆中,写屏障关闭
GCoff 内存归还阶段,将过多的内存归还给操作系统,写屏障关闭。
GC 如何调优
通过 go tool pprof 和 go tool trace 等工具 控制内存分配的速度,限制 Goroutine 的数量,从而提高赋值器对 CPU 的利用率。
减少并复用内存,例如使用 sync.Pool 来复用需要频繁创建临时对象,例 如提前分配足够的内存来降低多余的拷贝。
需要时,增大 GOGC 的值,降低 GC 的运行频率
go map 也做GC
在 Golang 中的 map 结构,在删除键值对的时候,并不会真正的删除,而是标记。那么随着键值对越来越多,会不会造成大量内存浪费?会,很有可能导致 OOM
在 Go 语言中,map 是一种引用类型,它会通过垃圾回收器(GC)进行内存管理。
当一个 map 对象不再被引用时,也就是没有任何变量指向该 map 对象时,它会被标记为不再使用的对象,并在下一次垃圾回收时被回收。垃圾回收器会识别并回收这些不再使用的 map 对象所占用的内存。
垃圾回收器是自动管理内存的,它会根据一定的策略和算法来判断对象是否可达(reachable),并进行回收。因此,无需手动释放 map 对象的内存。
重要的是要确保在程序中没有任何引用指向 map 对象时,以便让垃圾回收器能够正确地识别并回收这些对象。如果的程序中有大量的不再使用的 map 对象,可以确保及时将其设置为 nil 或让其超出作用域,以帮助垃圾回收器更早地回收这些对象。
map 对象会通过垃圾回收器进行自动内存管理,当一个 map 对象不再被引用时,它会被垃圾回收器回收。无需手动释放 map 对象的内存,但需要确保在不需要使用 map 对象时将其设置为 nil 或让其超出作用域,以帮助垃圾回收器及时回收内存。