Home | History | Annotate | Download | only in pprof
      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
      6 
      7 import (
      8 	"bytes"
      9 	"fmt"
     10 	"reflect"
     11 	"regexp"
     12 	"runtime"
     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 // Allocate transient memory using reflect.Call.
     46 
     47 func allocateReflectTransient() {
     48 	memSink = make([]byte, 2<<20)
     49 }
     50 
     51 func allocateReflect() {
     52 	rv := reflect.ValueOf(allocateReflectTransient)
     53 	rv.Call(nil)
     54 }
     55 
     56 var memoryProfilerRun = 0
     57 
     58 func TestMemoryProfiler(t *testing.T) {
     59 	// Disable sampling, otherwise it's difficult to assert anything.
     60 	oldRate := runtime.MemProfileRate
     61 	runtime.MemProfileRate = 1
     62 	defer func() {
     63 		runtime.MemProfileRate = oldRate
     64 	}()
     65 
     66 	// Allocate a meg to ensure that mcache.next_sample is updated to 1.
     67 	for i := 0; i < 1024; i++ {
     68 		memSink = make([]byte, 1024)
     69 	}
     70 
     71 	// Do the interesting allocations.
     72 	allocateTransient1M()
     73 	allocateTransient2M()
     74 	allocatePersistent1K()
     75 	allocateReflect()
     76 	memSink = nil
     77 
     78 	runtime.GC() // materialize stats
     79 	var buf bytes.Buffer
     80 	if err := Lookup("heap").WriteTo(&buf, 1); err != nil {
     81 		t.Fatalf("failed to write heap profile: %v", err)
     82 	}
     83 
     84 	memoryProfilerRun++
     85 
     86 	tests := []string{
     87 		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]+
     88 #	0x[0-9,a-f]+	runtime/pprof\.allocatePersistent1K\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:40
     89 #	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:74
     90 `, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun),
     91 
     92 		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]+
     93 #	0x[0-9,a-f]+	runtime/pprof\.allocateTransient1M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:21
     94 #	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:72
     95 `, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun),
     96 
     97 		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]+
     98 #	0x[0-9,a-f]+	runtime/pprof\.allocateTransient2M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:27
     99 #	0x[0-9,a-f]+	runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:73
    100 `, memoryProfilerRun, (2<<20)*memoryProfilerRun),
    101 
    102 		fmt.Sprintf(`0: 0 \[%v: %v\] @( 0x[0-9,a-f]+)+
    103 #	0x[0-9,a-f]+	runtime/pprof\.allocateReflectTransient\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:48
    104 `, memoryProfilerRun, (2<<20)*memoryProfilerRun),
    105 	}
    106 
    107 	for _, test := range tests {
    108 		if !regexp.MustCompile(test).Match(buf.Bytes()) {
    109 			t.Fatalf("The entry did not match:\n%v\n\nProfile:\n%v\n", test, buf.String())
    110 		}
    111 	}
    112 }
    113