1
2
3
4
5 package pprof
6
7 import (
8 "internal/profilerecord"
9 "io"
10 "math"
11 "runtime"
12 "strings"
13 )
14
15
16 func writeHeapProto(w io.Writer, p []profilerecord.MemProfileRecord, rate int64, defaultSampleType string) error {
17 b := newProfileBuilder(w)
18 b.pbValueType(tagProfile_PeriodType, "space", "bytes")
19 b.pb.int64Opt(tagProfile_Period, rate)
20 b.pbValueType(tagProfile_SampleType, "alloc_objects", "count")
21 b.pbValueType(tagProfile_SampleType, "alloc_space", "bytes")
22 b.pbValueType(tagProfile_SampleType, "inuse_objects", "count")
23 b.pbValueType(tagProfile_SampleType, "inuse_space", "bytes")
24 if defaultSampleType != "" {
25 b.pb.int64Opt(tagProfile_DefaultSampleType, b.stringIndex(defaultSampleType))
26 }
27
28 values := []int64{0, 0, 0, 0}
29 var locs []uint64
30 for _, r := range p {
31 hideRuntime := true
32 for tries := 0; tries < 2; tries++ {
33 stk := r.Stack
34
35
36
37 if hideRuntime {
38 for i, addr := range stk {
39 if f := runtime.FuncForPC(addr); f != nil && strings.HasPrefix(f.Name(), "runtime.") {
40 continue
41 }
42
43 stk = stk[i:]
44 break
45 }
46 }
47 locs = b.appendLocsForStack(locs[:0], stk)
48 if len(locs) > 0 {
49 break
50 }
51 hideRuntime = false
52 }
53
54 values[0], values[1] = scaleHeapSample(r.AllocObjects, r.AllocBytes, rate)
55 values[2], values[3] = scaleHeapSample(r.InUseObjects(), r.InUseBytes(), rate)
56 var blockSize int64
57 if r.AllocObjects > 0 {
58 blockSize = r.AllocBytes / r.AllocObjects
59 }
60 b.pbSample(values, locs, func() {
61 if blockSize != 0 {
62 b.pbLabel(tagSample_Label, "bytes", "", blockSize)
63 }
64 })
65 }
66 b.build()
67 return nil
68 }
69
70
71
72
73
74
75
76
77
78
79 func scaleHeapSample(count, size, rate int64) (int64, int64) {
80 if count == 0 || size == 0 {
81 return 0, 0
82 }
83
84 if rate <= 1 {
85
86
87 return count, size
88 }
89
90 avgSize := float64(size) / float64(count)
91 scale := 1 / (1 - math.Exp(-avgSize/float64(rate)))
92
93 return int64(float64(count) * scale), int64(float64(size) * scale)
94 }
95
View as plain text