Official document: [https://godoc.org/sync#Pool]
The usage of sync.Pool
is a very common in high concurrency scenarios. You may create tons of goroutines and each of them allocates short-lived objects and later cause a slow GC.
With sync.Pool
we can avoid this. Objects inside the pool will be cleaned after GC without any notification, so sync.Pool
is not suitable for connection pool.
The objects being Put()
back into the pool may be Get()
and reused before GC happens. This means you have the chance to Get()
a object with old values.
Example here:
package main
import (
"fmt"
"runtime"
"runtime/debug"
"sync"
)
func main() {
newFunc := func() interface{} {
return make([]byte, 32)
}
pool := sync.Pool{New: newFunc}
v1 := pool.Get().([]byte)
fmt.Printf("v1: %v\n", v1)
v1[0] = 1
fmt.Printf("modified v1: %v\n", v1)
// modified v1, put back to pool, before GC
pool.Put(v1)
v2 := pool.Get().([]byte)
fmt.Printf("v2: %v\n", v2)
pool.Put(v2)
// After GC
debug.SetGCPercent(100)
runtime.GC()
v3 := pool.Get().([]byte)
fmt.Printf("v3: %v\n", v3)
}
So do remember to clean the object before you Put()
back, or init the object right after you Get()
to prevent any accident.
Top comments (0)