github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/runtime/malloc_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime_test 6 7 import ( 8 "flag" 9 . "runtime" 10 "testing" 11 "time" 12 "unsafe" 13 ) 14 15 func TestMemStats(t *testing.T) { 16 // Test that MemStats has sane values. 17 st := new(MemStats) 18 ReadMemStats(st) 19 20 // Everything except HeapReleased and HeapIdle, because they indeed can be 0. 21 if st.Alloc == 0 || st.TotalAlloc == 0 || st.Sys == 0 || st.Lookups == 0 || 22 st.Mallocs == 0 || st.Frees == 0 || st.HeapAlloc == 0 || st.HeapSys == 0 || 23 st.HeapInuse == 0 || st.HeapObjects == 0 || st.StackInuse == 0 || 24 st.StackSys == 0 || st.MSpanInuse == 0 || st.MSpanSys == 0 || st.MCacheInuse == 0 || 25 st.MCacheSys == 0 || st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 || 26 st.NextGC == 0 || st.NumGC == 0 { 27 t.Fatalf("Zero value: %+v", *st) 28 } 29 30 if st.Alloc > 1e10 || st.TotalAlloc > 1e11 || st.Sys > 1e10 || st.Lookups > 1e10 || 31 st.Mallocs > 1e10 || st.Frees > 1e10 || st.HeapAlloc > 1e10 || st.HeapSys > 1e10 || 32 st.HeapIdle > 1e10 || st.HeapInuse > 1e10 || st.HeapObjects > 1e10 || st.StackInuse > 1e10 || 33 st.StackSys > 1e10 || st.MSpanInuse > 1e10 || st.MSpanSys > 1e10 || st.MCacheInuse > 1e10 || 34 st.MCacheSys > 1e10 || st.BuckHashSys > 1e10 || st.GCSys > 1e10 || st.OtherSys > 1e10 || 35 st.NextGC > 1e10 || st.NumGC > 1e9 { 36 t.Fatalf("Insanely high value (overflow?): %+v", *st) 37 } 38 39 if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+ 40 st.BuckHashSys+st.GCSys+st.OtherSys { 41 t.Fatalf("Bad sys value: %+v", *st) 42 } 43 44 if st.HeapIdle+st.HeapInuse != st.HeapSys { 45 t.Fatalf("HeapIdle(%d) + HeapInuse(%d) should be equal to HeapSys(%d), but isn't.", st.HeapIdle, st.HeapInuse, st.HeapSys) 46 } 47 } 48 49 var mallocSink uintptr 50 51 func BenchmarkMalloc8(b *testing.B) { 52 var x uintptr 53 for i := 0; i < b.N; i++ { 54 p := new(int64) 55 x ^= uintptr(unsafe.Pointer(p)) 56 } 57 mallocSink = x 58 } 59 60 func BenchmarkMalloc16(b *testing.B) { 61 var x uintptr 62 for i := 0; i < b.N; i++ { 63 p := new([2]int64) 64 x ^= uintptr(unsafe.Pointer(p)) 65 } 66 mallocSink = x 67 } 68 69 func BenchmarkMallocTypeInfo8(b *testing.B) { 70 var x uintptr 71 for i := 0; i < b.N; i++ { 72 p := new(struct { 73 p [8 / unsafe.Sizeof(uintptr(0))]*int 74 }) 75 x ^= uintptr(unsafe.Pointer(p)) 76 } 77 mallocSink = x 78 } 79 80 func BenchmarkMallocTypeInfo16(b *testing.B) { 81 var x uintptr 82 for i := 0; i < b.N; i++ { 83 p := new(struct { 84 p [16 / unsafe.Sizeof(uintptr(0))]*int 85 }) 86 x ^= uintptr(unsafe.Pointer(p)) 87 } 88 mallocSink = x 89 } 90 91 type LargeStruct struct { 92 x [16][]byte 93 } 94 95 func BenchmarkMallocLargeStruct(b *testing.B) { 96 var x uintptr 97 for i := 0; i < b.N; i++ { 98 p := make([]LargeStruct, 2) 99 x ^= uintptr(unsafe.Pointer(&p[0])) 100 } 101 mallocSink = x 102 } 103 104 var n = flag.Int("n", 1000, "number of goroutines") 105 106 func BenchmarkGoroutineSelect(b *testing.B) { 107 quit := make(chan struct{}) 108 read := func(ch chan struct{}) { 109 for { 110 select { 111 case _, ok := <-ch: 112 if !ok { 113 return 114 } 115 case <-quit: 116 return 117 } 118 } 119 } 120 benchHelper(b, *n, read) 121 } 122 123 func BenchmarkGoroutineBlocking(b *testing.B) { 124 read := func(ch chan struct{}) { 125 for { 126 if _, ok := <-ch; !ok { 127 return 128 } 129 } 130 } 131 benchHelper(b, *n, read) 132 } 133 134 func BenchmarkGoroutineForRange(b *testing.B) { 135 read := func(ch chan struct{}) { 136 for range ch { 137 } 138 } 139 benchHelper(b, *n, read) 140 } 141 142 func benchHelper(b *testing.B, n int, read func(chan struct{})) { 143 m := make([]chan struct{}, n) 144 for i := range m { 145 m[i] = make(chan struct{}, 1) 146 go read(m[i]) 147 } 148 b.StopTimer() 149 b.ResetTimer() 150 GC() 151 152 for i := 0; i < b.N; i++ { 153 for _, ch := range m { 154 if ch != nil { 155 ch <- struct{}{} 156 } 157 } 158 time.Sleep(10 * time.Millisecond) 159 b.StartTimer() 160 GC() 161 b.StopTimer() 162 } 163 164 for _, ch := range m { 165 close(ch) 166 } 167 time.Sleep(10 * time.Millisecond) 168 } 169 170 func BenchmarkGoroutineIdle(b *testing.B) { 171 quit := make(chan struct{}) 172 fn := func() { 173 <-quit 174 } 175 for i := 0; i < *n; i++ { 176 go fn() 177 } 178 179 GC() 180 b.ResetTimer() 181 182 for i := 0; i < b.N; i++ { 183 GC() 184 } 185 186 b.StopTimer() 187 close(quit) 188 time.Sleep(10 * time.Millisecond) 189 }