Open seehuhn opened 7 months ago
There is some additional discussion (from long ago) on the golang-nuts
mailing list: https://groups.google.com/g/golang-nuts/c/Bzgcn-9o1Yg/m/gLxGmXm-AAAJ
Type: inuse_space
You are looking at the in-use space, of which there won't be any by the time you are taking the profile. Try go tool pprof --alloc_space mem.prof
Then, isn't the documentation at https://pkg.go.dev/runtime/pprof#hdr-Profiling_a_Go_program wrong, or at least very unhelpful?
Turns out the documentation is wrong! When I turn my code into a unit test, then go tool pprof mem.prof
(without the extra option) shows the allocations, and the documentation claims that the code I used would "add equivalent profiling support to a standalone program", when my experiment shows it is different.
Here is my new code:
func TestMemprofile(t *testing.T) {
c := make(chan []float64)
go func() {
for i := 0; i < 1000; i++ {
data := make([]float64, 16*1024)
data[0] = float64(i)
c <- data
}
close(c)
}()
var sum float64
for data := range c {
sum += data[0]
}
fmt.Println(sum)
}
And here is how the pprof call now works as described in the docs (i.e. without the extra option):
voss@dumpling [~/Desktop/xxx] go test -memprofile=mem.prof
499500
PASS
ok example.com/m 0.208s
voss@dumpling [~/Desktop/xxx] go tool pprof mem.prof
Type: alloc_space
Time: Jan 27, 2024 at 4:58pm (GMT)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 104.54MB, 100% of 104.54MB total
flat flat% sum% cum cum%
104.54MB 100% 100% 104.54MB 100% example.com/m.TestMemprofile.func1
You're correct that there is a slight difference between the behavior of testing
and the suggested code snippet. testing
writes a memory profile that defaults to alloc_sace, whereas pprof.WriteHeapProfile writes a memory profile that defaults to inuse_space. Both write the same profile that includes both sample types, but they default to different types.
Maybe this could be explained in the documentation: Maybe the example code in the documentation could be changed to match what testing is going? Or the difference between testing and the example code could be explained there, together with the --alloc_space
option?
Or maybe WriteHeapProfile
could be changed to be a shorthand for Lookup("allocs")
instead of Lookup("heap")
? After all, this function is documented as being "preserved for backwards compatibility", and the change would restore the original behaviour of this function and also would make the code on https://go.dev/blog/pprof work again.
I have no opinions on that, but have reopened the issue so it'll be on the radar of the other team members.
In triage, we should probably align the default sample_index
for the two profiles, but this problem doesn't seem too severe. (Ignoring the discoverability of different sample_index
values; perhaps that should be mentioned in the documentation, if it isn't already.)
EDIT: Though, perhaps there are arguments for not aligning the two. I'm not sure.
I'm not sure we can/should align the two.
The testing package writes an alloc profile because the inuse profile is expected to be essentially empty and thus useless in tests.
On the other hand, pprof.WriteHeapProfile
is documented to report a heap profile (aka inuse), so a change here would not be backwards compatible.
I agree that https://pkg.go.dev/runtime/pprof#hdr-Profiling_a_Go_program is a little misleading and could be improved.
Change https://go.dev/cl/597980 mentions this issue: runtime/pprof: note different between go test -memprofile and WriteHeapProfile
Go version
go version go1.21.6 darwin/arm64
Output of
go env
in your module/workspace:What did you do?
I followed the instructions at https://pkg.go.dev/runtime/pprof#hdr-Profiling_a_Go_program , trying to get a memory profile of my program. Here is a short program, which illustrates the problem:
What did you see happen?
The profiler did not report the memory allocations:
What did you expect to see?
I would have expected the line
data := make([]float64, 16*1024)
to feature prominently in thego tool pprof
output.