Go语言中如何等待GC完成后再运行下一个基准测试
解决方案
Go标准库提供了直接满足需求的能力,主动调用runtime.GC()即可触发全量垃圾回收,且该调用会阻塞到GC完全执行完成后才会返回,刚好可以解决你遇到的基准测试互相干扰的问题。
用法示例
场景1:两个独立的基准测试函数
在BenchmarkNumCPU的计时开始前,先主动调用一次GC清理前序测试产生的垃圾:
import ( "runtime" "testing" ) func BenchmarkUnlimited(b *testing.B) { // 原有测试逻辑 } func BenchmarkNumCPU(b *testing.B) { // 等待前序测试产生的垃圾完全回收 runtime.GC() // 重置计时器,排除GC等待时间对当前基准测试结果的影响 b.ResetTimer() for i := 0; i < b.N; i++ { // 原有测试逻辑 } }
场景2:同一个基准测试内包含多段测试逻辑
在两段测试逻辑之间插入GC等待,同时配合计时器启停避免GC时间计入测试结果:
func BenchmarkCombined(b *testing.B) { // 第一段测试:BenchmarkUnlimited逻辑 for i := 0; i < b.N; i++ { // 大量分配内存的运算逻辑 } // 停止计时,清理垃圾 b.StopTimer() runtime.GC() // 重置计时器后启动第二段测试 b.ResetTimer() b.StartTimer() // 第二段测试:BenchmarkNumCPU逻辑 for i := 0; i < b.N; i++ { // 测试逻辑 } }
可选增强
如果需要更彻底地释放内存还给操作系统,可以在runtime.GC()之后追加调用debug.FreeOSMemory(),该操作会强制将闲置的内存页返还给系统,进一步降低残留内存对后续测试的影响:
import "runtime/debug" // ... runtime.GC() debug.FreeOSMemory() // ...
内容的提问来源于stack exchange,提问作者Timo Huovinen
相关产品推荐
相关产品推荐

