github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/runtime/gc_test.go (about) 1 // Copyright 2011 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 "os" 9 "runtime" 10 "runtime/debug" 11 "testing" 12 ) 13 14 func TestGcSys(t *testing.T) { 15 if os.Getenv("GOGC") == "off" { 16 t.Skip("skipping test; GOGC=off in environment") 17 } 18 data := struct{ Short bool }{testing.Short()} 19 got := executeTest(t, testGCSysSource, &data) 20 want := "OK\n" 21 if got != want { 22 t.Fatalf("expected %q, but got %q", want, got) 23 } 24 } 25 26 const testGCSysSource = ` 27 package main 28 29 import ( 30 "fmt" 31 "runtime" 32 ) 33 34 func main() { 35 runtime.GOMAXPROCS(1) 36 memstats := new(runtime.MemStats) 37 runtime.GC() 38 runtime.ReadMemStats(memstats) 39 sys := memstats.Sys 40 41 runtime.MemProfileRate = 0 // disable profiler 42 43 itercount := 1000000 44 {{if .Short}} 45 itercount = 100000 46 {{end}} 47 for i := 0; i < itercount; i++ { 48 workthegc() 49 } 50 51 // Should only be using a few MB. 52 // We allocated 100 MB or (if not short) 1 GB. 53 runtime.ReadMemStats(memstats) 54 if sys > memstats.Sys { 55 sys = 0 56 } else { 57 sys = memstats.Sys - sys 58 } 59 if sys > 16<<20 { 60 fmt.Printf("using too much memory: %d bytes\n", sys) 61 return 62 } 63 fmt.Printf("OK\n") 64 } 65 66 func workthegc() []byte { 67 return make([]byte, 1029) 68 } 69 ` 70 71 func TestGcDeepNesting(t *testing.T) { 72 type T [2][2][2][2][2][2][2][2][2][2]*int 73 a := new(T) 74 75 // Prevent the compiler from applying escape analysis. 76 // This makes sure new(T) is allocated on heap, not on the stack. 77 t.Logf("%p", a) 78 79 a[0][0][0][0][0][0][0][0][0][0] = new(int) 80 *a[0][0][0][0][0][0][0][0][0][0] = 13 81 runtime.GC() 82 if *a[0][0][0][0][0][0][0][0][0][0] != 13 { 83 t.Fail() 84 } 85 } 86 87 func TestGcHashmapIndirection(t *testing.T) { 88 defer debug.SetGCPercent(debug.SetGCPercent(1)) 89 runtime.GC() 90 type T struct { 91 a [256]int 92 } 93 m := make(map[T]T) 94 for i := 0; i < 2000; i++ { 95 var a T 96 a.a[0] = i 97 m[a] = T{} 98 } 99 } 100 101 func TestGcArraySlice(t *testing.T) { 102 type X struct { 103 buf [1]byte 104 nextbuf []byte 105 next *X 106 } 107 var head *X 108 for i := 0; i < 10; i++ { 109 p := &X{} 110 p.buf[0] = 42 111 p.next = head 112 if head != nil { 113 p.nextbuf = head.buf[:] 114 } 115 head = p 116 runtime.GC() 117 } 118 for p := head; p != nil; p = p.next { 119 if p.buf[0] != 42 { 120 t.Fatal("corrupted heap") 121 } 122 } 123 } 124 125 func TestGcRescan(t *testing.T) { 126 type X struct { 127 c chan error 128 nextx *X 129 } 130 type Y struct { 131 X 132 nexty *Y 133 p *int 134 } 135 var head *Y 136 for i := 0; i < 10; i++ { 137 p := &Y{} 138 p.c = make(chan error) 139 if head != nil { 140 p.nextx = &head.X 141 } 142 p.nexty = head 143 p.p = new(int) 144 *p.p = 42 145 head = p 146 runtime.GC() 147 } 148 for p := head; p != nil; p = p.nexty { 149 if *p.p != 42 { 150 t.Fatal("corrupted heap") 151 } 152 } 153 }