github.com/aloncn/graphics-go@v0.0.1/src/runtime/pprof/mprof_test.go (about) 1 // Copyright 2014 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 pprof_test 6 7 import ( 8 "bytes" 9 "fmt" 10 "regexp" 11 "runtime" 12 . "runtime/pprof" 13 "testing" 14 "unsafe" 15 ) 16 17 var memSink interface{} 18 19 func allocateTransient1M() { 20 for i := 0; i < 1024; i++ { 21 memSink = &struct{ x [1024]byte }{} 22 } 23 } 24 25 //go:noinline 26 func allocateTransient2M() { 27 memSink = make([]byte, 2<<20) 28 } 29 30 type Obj32 struct { 31 link *Obj32 32 pad [32 - unsafe.Sizeof(uintptr(0))]byte 33 } 34 35 var persistentMemSink *Obj32 36 37 func allocatePersistent1K() { 38 for i := 0; i < 32; i++ { 39 // Can't use slice because that will introduce implicit allocations. 40 obj := &Obj32{link: persistentMemSink} 41 persistentMemSink = obj 42 } 43 } 44 45 var memoryProfilerRun = 0 46 47 func TestMemoryProfiler(t *testing.T) { 48 // Disable sampling, otherwise it's difficult to assert anything. 49 oldRate := runtime.MemProfileRate 50 runtime.MemProfileRate = 1 51 defer func() { 52 runtime.MemProfileRate = oldRate 53 }() 54 55 // Allocate a meg to ensure that mcache.next_sample is updated to 1. 56 for i := 0; i < 1024; i++ { 57 memSink = make([]byte, 1024) 58 } 59 60 // Do the interesting allocations. 61 allocateTransient1M() 62 allocateTransient2M() 63 allocatePersistent1K() 64 memSink = nil 65 66 runtime.GC() // materialize stats 67 var buf bytes.Buffer 68 if err := Lookup("heap").WriteTo(&buf, 1); err != nil { 69 t.Fatalf("failed to write heap profile: %v", err) 70 } 71 72 memoryProfilerRun++ 73 74 tests := []string{ 75 fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 76 # 0x[0-9,a-f]+ runtime/pprof_test\.allocatePersistent1K\+0x[0-9,a-f]+ .*/runtime/pprof/mprof_test\.go:40 77 # 0x[0-9,a-f]+ runtime/pprof_test\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/runtime/pprof/mprof_test\.go:63 78 `, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun), 79 80 fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 81 # 0x[0-9,a-f]+ runtime/pprof_test\.allocateTransient1M\+0x[0-9,a-f]+ .*/runtime/pprof/mprof_test.go:21 82 # 0x[0-9,a-f]+ runtime/pprof_test\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/runtime/pprof/mprof_test.go:61 83 `, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun), 84 85 fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 86 # 0x[0-9,a-f]+ runtime/pprof_test\.allocateTransient2M\+0x[0-9,a-f]+ .*/runtime/pprof/mprof_test.go:27 87 # 0x[0-9,a-f]+ runtime/pprof_test\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/runtime/pprof/mprof_test.go:62 88 `, memoryProfilerRun, (2<<20)*memoryProfilerRun), 89 } 90 91 for _, test := range tests { 92 if !regexp.MustCompile(test).Match(buf.Bytes()) { 93 t.Fatalf("The entry did not match:\n%v\n\nProfile:\n%v\n", test, buf.String()) 94 } 95 } 96 }