github.com/hongwozai/go-src-1.4.3@v0.0.0-20191127132709-dc3fce3dbccb/test/fixedbugs/issue9110.go (about) 1 // run 2 3 // Copyright 2014 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // Scenario that used to leak arbitrarily many SudoG structs. 8 // See golang.org/issue/9110. 9 10 package main 11 12 import ( 13 "runtime" 14 "runtime/debug" 15 "sync" 16 "time" 17 ) 18 19 func main() { 20 debug.SetGCPercent(1000000) // only GC when we ask for GC 21 22 var stats, stats1, stats2 runtime.MemStats 23 24 release := func() {} 25 for i := 0; i < 20; i++ { 26 if i == 10 { 27 // Should be warmed up by now. 28 runtime.ReadMemStats(&stats1) 29 } 30 31 c := make(chan int) 32 for i := 0; i < 10; i++ { 33 go func() { 34 select { 35 case <-c: 36 case <-c: 37 case <-c: 38 } 39 }() 40 } 41 time.Sleep(1 * time.Millisecond) 42 release() 43 44 close(c) // let select put its sudog's into the cache 45 time.Sleep(1 * time.Millisecond) 46 47 // pick up top sudog 48 var cond1 sync.Cond 49 var mu1 sync.Mutex 50 cond1.L = &mu1 51 go func() { 52 mu1.Lock() 53 cond1.Wait() 54 mu1.Unlock() 55 }() 56 time.Sleep(1 * time.Millisecond) 57 58 // pick up next sudog 59 var cond2 sync.Cond 60 var mu2 sync.Mutex 61 cond2.L = &mu2 62 go func() { 63 mu2.Lock() 64 cond2.Wait() 65 mu2.Unlock() 66 }() 67 time.Sleep(1 * time.Millisecond) 68 69 // put top sudog back 70 cond1.Broadcast() 71 time.Sleep(1 * time.Millisecond) 72 73 // drop cache on floor 74 runtime.GC() 75 76 // release cond2 after select has gotten to run 77 release = func() { 78 cond2.Broadcast() 79 time.Sleep(1 * time.Millisecond) 80 } 81 } 82 83 runtime.GC() 84 85 runtime.ReadMemStats(&stats2) 86 87 if int(stats2.HeapObjects)-int(stats1.HeapObjects) > 20 { // normally at most 1 or 2; was 300 with leak 88 print("BUG: object leak: ", stats.HeapObjects, " -> ", stats1.HeapObjects, " -> ", stats2.HeapObjects, "\n") 89 } 90 }