var pool = sync.Pool{ New: func()interface{} { returnnew(Hello) }, }
funcsay(self *Hello) { self.a++ }
funcBenchmarkWithoutPool(b *testing.B) { var s *Hello for i := 0; i < b.N; i++ { s = &Hello{a: 1,} b.StopTimer(); say(s); b.StartTimer() } }
funcBenchmarkWithPool(b *testing.B) { var s *Hello for i := 0; i < b.N; i++ { s = pool.Get().(*Hello) s.a = 1 b.StopTimer(); say(s); b.StartTimer() pool.Put(s) } }
// 清空pool funcpoolCleanup() { // This function is called with the world stopped, at the beginning of a garbage collection. // It must not allocate and probably should not call any runtime functions.
// Because the world is stopped, no pool user can be in a // pinned section (in effect, this has all Ps pinned).
// Drop victim caches from all pools. for _, p := range oldPools { p.victim = nil p.victimSize = 0 }
// Move primary cache to victim cache. for _, p := range allPools { p.victim = p.local p.victimSize = p.localSize p.local = nil p.localSize = 0 }
// The pools with non-empty primary caches now have non-empty // victim caches and no pools have primary caches. oldPools, allPools = allPools, nil }
var ( allPoolsMu Mutex
// allPools is the set of pools that have non-empty primary // caches. Protected by either 1) allPoolsMu and pinning or 2) // STW. allPools []*Pool
// oldPools is the set of pools that may have non-empty victim // caches. Protected by STW. oldPools []*Pool )
// Clear central sudog cache. // Leave per-P caches alone, they have strictly bounded size. // Disconnect cached list before dropping it on the floor, // so that a dangling ref to one entry does not pin all of them. lock(&sched.sudoglock) var sg, sgnext *sudog for sg = sched.sudogcache; sg != nil; sg = sgnext { sgnext = sg.next sg.next = nil } sched.sudogcache = nil unlock(&sched.sudoglock)
// Clear central defer pools. // Leave per-P pools alone, they have strictly bounded size. lock(&sched.deferlock) for i := range sched.deferpool { // disconnect cached list before dropping it on the floor, // so that a dangling ref to one entry does not pin all of them. var d, dlink *_defer for d = sched.deferpool[i]; d != nil; d = dlink { dlink = d.link d.link = nil } sched.deferpool[i] = nil } unlock(&sched.deferlock) }
// gcStart starts the GC. It transitions from _GCoff to _GCmark (if // debug.gcstoptheworld == 0) or performs all of GC (if // debug.gcstoptheworld != 0). // // This may return without performing this transition in some cases, // such as when called on a system stack or with locks held. funcgcStart(trigger gcTrigger) {