diff options
| author | Hana (Hyang-Ah) Kim <hyangah@gmail.com> | 2018-03-27 12:23:19 -0400 |
|---|---|---|
| committer | Hyang-Ah Hana Kim <hyangah@gmail.com> | 2018-04-24 16:11:41 +0000 |
| commit | cd037bce09ec1aecd40d9c91c23d09f5b60549f4 (patch) | |
| tree | 932329eed8ad31e2e06750de1afe7976244a4753 /src/runtime/pprof/pprof.go | |
| parent | 70c5839fe0e2149d505c0e28c42e133d4bc01503 (diff) | |
| download | go-cd037bce09ec1aecd40d9c91c23d09f5b60549f4.tar.xz | |
runtime/pprof: introduce "allocs" profile
The Go's heap profile contains four kinds of samples
(inuse_space, inuse_objects, alloc_space, and alloc_objects).
The pprof tool by default chooses the inuse_space (the bytes
of live, in-use objects). When analyzing the current memory
usage the choice of inuse_space as the default may be useful,
but in some cases, users are more interested in analyzing the
total allocation statistics throughout the program execution.
For example, when we analyze the memory profile from benchmark
or program test run, we are more likely interested in the whole
allocation history than the live heap snapshot at the end of
the test or benchmark.
The pprof tool provides flags to control which sample type
to be used for analysis. However, it is one of the less-known
features of pprof and we believe it's better to choose the
right type of samples as the default when producing the profile.
This CL introduces a new type of profile, "allocs", which is
the same as the "heap" profile but marks the alloc_space
as the default type unlike heap profiles that use inuse_space
as the default type.
'go test -memprofile=...' command is changed to use the new
"allocs" profile type instead of the traditional "heap" profile.
Fixes #24443
Change-Id: I012dd4b6dcacd45644d7345509936b8380b6fbd9
Reviewed-on: https://go-review.googlesource.com/102696
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/pprof/pprof.go')
| -rw-r--r-- | src/runtime/pprof/pprof.go | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go index b7e5a1f92f..39126ba148 100644 --- a/src/runtime/pprof/pprof.go +++ b/src/runtime/pprof/pprof.go @@ -99,7 +99,8 @@ import ( // Each Profile has a unique name. A few profiles are predefined: // // goroutine - stack traces of all current goroutines -// heap - a sampling of all heap allocations +// heap - a sampling of memory allocations of live objects +// allocs - a sampling of all past memory allocations // threadcreate - stack traces that led to the creation of new OS threads // block - stack traces that led to blocking on synchronization primitives // mutex - stack traces of holders of contended mutexes @@ -114,6 +115,16 @@ import ( // all known allocations. This exception helps mainly in programs running // without garbage collection enabled, usually for debugging purposes. // +// The heap profile tracks both the allocation sites for all live objects in +// the application memory and for all objects allocated since the program start. +// Pprof's -inuse_space, -inuse_objects, -alloc_space, and -alloc_objects +// flags select which to display, defaulting to -inuse_space (live objects, +// scaled by size). +// +// The allocs profile is the same as the heap profile but changes the default +// pprof display to -alloc_space, the total number of bytes allocated since +// the program began (including garbage-collected bytes). +// // The CPU profile is not available as a Profile. It has a special API, // the StartCPUProfile and StopCPUProfile functions, because it streams // output to a writer during profiling. @@ -150,6 +161,12 @@ var heapProfile = &Profile{ write: writeHeap, } +var allocsProfile = &Profile{ + name: "allocs", + count: countHeap, // identical to heap profile + write: writeAlloc, +} + var blockProfile = &Profile{ name: "block", count: countBlock, @@ -170,6 +187,7 @@ func lockProfiles() { "goroutine": goroutineProfile, "threadcreate": threadcreateProfile, "heap": heapProfile, + "allocs": allocsProfile, "block": blockProfile, "mutex": mutexProfile, } @@ -511,6 +529,16 @@ func countHeap() int { // writeHeap writes the current runtime heap profile to w. func writeHeap(w io.Writer, debug int) error { + return writeHeapInternal(w, debug, "") +} + +// writeAlloc writes the current runtime heap profile to w +// with the total allocation space as the default sample type. +func writeAlloc(w io.Writer, debug int) error { + return writeHeapInternal(w, debug, "alloc_space") +} + +func writeHeapInternal(w io.Writer, debug int, defaultSampleType string) error { var memStats *runtime.MemStats if debug != 0 { // Read mem stats first, so that our other allocations @@ -541,7 +569,7 @@ func writeHeap(w io.Writer, debug int) error { } if debug == 0 { - return writeHeapProto(w, p, int64(runtime.MemProfileRate)) + return writeHeapProto(w, p, int64(runtime.MemProfileRate), defaultSampleType) } sort.Slice(p, func(i, j int) bool { return p[i].InUseBytes() > p[j].InUseBytes() }) |
