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