-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Here is a gist containing a program that does the following:
- Set
runtime.MemProfileRateto 1. - Read a flag-controlled number of zeroes from
/dev/zerousingioutil.ReadAllandio.LimitReader. - Call
io.MultiWriter1024 times in a loop, encouraging it to make allocations. - Write out a heap profile to
/tmp/mem.pprof.
When I run the program with the flag that tells it to read 2096128 bytes before calling io.MultiWriter, I see the expected number of calls in the profile:
% go build main.go && ./main --size 2096128 && grep -B 1 MultiWriter /tmp/mem.pprof
1024: 32768 [1024: 32768] @ 0x43aaf5 0x45dd38 0x400f60 0x4010a1 0x42a3ff 0x456331
# 0x45dd38 io.MultiWriter+0x48 /usr/local/google/home/jacobsa/clients/go/src/io/multi.go:58
--
996: 31872 [1024: 32768] @ 0x45dda3 0x400f60 0x4010a1 0x42a3ff 0x456331
# 0x45dda3 io.MultiWriter+0xb3 /usr/local/google/home/jacobsa/clients/go/src/io/multi.go:60
However, with any value above this I get unreliable results (these change from run to run, but are never the full count and are often zero):
% go build main.go && ./main --size 2096129 && grep -B 1 MultiWriter /tmp/mem.pprof
0: 0 [0: 0] @ 0x45dda3 0x400f60 0x4010a1 0x42a3ff 0x456331
# 0x45dda3 io.MultiWriter+0xb3 /usr/local/google/home/jacobsa/clients/go/src/io/multi.go:60
--
0: 0 [0: 0] @ 0x43aaf5 0x45dd38 0x400f60 0x4010a1 0x42a3ff 0x456331
# 0x45dd38 io.MultiWriter+0x48 /usr/local/google/home/jacobsa/clients/go/src/io/multi.go:58
This shows up as nonsense callgraphs in pprof, containing lots of runtime frames and the wrong counts for the functions I'm interested in. Compare this one to this one. Each is from an invocation of pprof that looks like:
go tool pprof -alloc_objects ~/tmp/59f9bbfa096fd3c595dc/main /tmp/mem.pprof
I have been unable to simplify the test case further. In particular, merely allocating a slice of bytes of the given size isn't good enough; it seems I have to open and read a file. I've also seen the problem when not setting runtime.MemProfileRate to a non-default value, but it is harder to reproduce.
go version:
go version devel +f2662f2 Tue Jun 23 03:18:52 2015 +0000 linux/amd64