1 // Copyright 2016 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.
8 "internal/pprof/profile"
14 // EncodeMemProfile converts MemProfileRecords to a Profile.
15 func EncodeMemProfile(mr
[]runtime
.MemProfileRecord
, rate
int64, t time
.Time
) *profile
.Profile
{
16 p
:= &profile
.Profile
{
18 PeriodType
: &profile
.ValueType
{Type
: "space", Unit
: "bytes"},
19 SampleType
: []*profile
.ValueType
{
20 {Type
: "alloc_objects", Unit
: "count"},
21 {Type
: "alloc_space", Unit
: "bytes"},
22 {Type
: "inuse_objects", Unit
: "count"},
23 {Type
: "inuse_space", Unit
: "bytes"},
25 TimeNanos
: int64(t
.UnixNano()),
28 locs
:= make(map[uintptr]*profile
.Location
)
29 for _
, r
:= range mr
{
31 sloc
:= make([]*profile
.Location
, len(stack
))
32 for i
, addr
:= range stack
{
35 loc
= &profile
.Location
{
36 ID
: uint64(len(p
.Location
) + 1),
37 Address
: uint64(addr
),
40 p
.Location
= append(p
.Location
, loc
)
45 ao
, ab
:= scaleHeapSample(r
.AllocObjects
, r
.AllocBytes
, rate
)
46 uo
, ub
:= scaleHeapSample(r
.InUseObjects(), r
.InUseBytes(), rate
)
48 p
.Sample
= append(p
.Sample
, &profile
.Sample
{
49 Value
: []int64{ao
, ab
, uo
, ub
},
53 if runtime
.GOOS
== "linux" {
59 // scaleHeapSample adjusts the data from a heap Sample to
60 // account for its probability of appearing in the collected
61 // data. heap profiles are a sampling of the memory allocations
62 // requests in a program. We estimate the unsampled value by dividing
63 // each collected sample by its probability of appearing in the
64 // profile. heap profiles rely on a poisson process to determine
65 // which samples to collect, based on the desired average collection
66 // rate R. The probability of a sample of size S to appear in that
67 // profile is 1-exp(-S/R).
68 func scaleHeapSample(count
, size
, rate
int64) (int64, int64) {
69 if count
== 0 || size
== 0 {
74 // if rate==1 all samples were collected so no adjustment is needed.
75 // if rate<1 treat as unknown and skip scaling.
79 avgSize
:= float64(size
) / float64(count
)
80 scale
:= 1 / (1 - math
.Exp(-avgSize
/float64(rate
)))
82 return int64(float64(count
) * scale
), int64(float64(size
) * scale
)