Search code examples
gogarbage-collectionbenchmarking

How to wait for garbage collection to complete?


I was wondering is there a way to wait for GC to finish?

Lets say I'm running benchmarks:

  • BenchmarkUnlimited (Does a lot of work)
  • BenchmarkNumCPU (Is affected by BenchmarkUnlimited)

The problem here is that BenchmarkUnlimited creates a lot of allocations, garbage collecting all of this takes time, but BenchmarkNumCPU is already running and its results can be affected by the previous benchmark.

Is there a way to tell the go program to wait for the GC to complete before running the next benchmark?


Solution

  • The Go benchmark framework already invokes runtime.GC() before running each benchmark.

    So there is no issue - you can rest assured each benchmark is started free of garbage from previous benchmarks.

    See go/src/testing/benchmark.go: (also notice the comment there)

    func (b *B) runN(n int) {
        benchmarkLock.Lock()
        defer benchmarkLock.Unlock()
        defer b.runCleanup(normalPanic)
        // Try to get a comparable environment for each run
        // by clearing garbage from previous runs.
        runtime.GC()                                    // <========== HERE
        b.raceErrors = -race.Errors()
        b.N = n
        b.parallelism = 1
        b.ResetTimer()
        b.StartTimer()
        b.benchFunc(b)
        b.StopTimer()
        . . .