Hi gophers!
I am doing a lot of automatic testing lately (to be exact, generation of automatic tests) and one category I am especially interested in is detecting memory leaks. I have three questions I need guidance with:
1. How can memory leaks be detected? If a function foo() is called, how can I deterministically detect that allocations/objects got leaked by this function or due to this function?
2. How can allocations/objects be marked? If the function foo() leaks an object of type bar, how can I state that such an object is leaking?
3. How can I trace a leaked object back to its location? Meaning, is it possible to get a stack trace of the allocation of a particular object?
I am wondering if the first question could be easily answered using runtime.GC() and runtime.ReadMemStats(m *MemStats). Please consider the following program
http://play.golang.org/p/0poBP631fc When I execute the given program I get the following output.
$ go version
go version go1.4 linux/amd64
$ go run -gcflags=-m tt.go
# command-line-arguments
./tt.go:24: can inline func·001
./tt.go:24: func literal escapes to heap
./tt.go:22: moved to heap: ch
./tt.go:25: &ch escapes to heap
./tt.go:22: make(chan bool, 0) escapes to heap
./tt.go:22: make(chan bool, 0) escapes to heap
./tt.go:21: <S> func literal does not escape
./tt.go:18: <S> &stats[1] does not escape
./tt.go:20: <S> func literal does not escape
./tt.go:38: <S> &stats[2] does not escape
./tt.go:10: main make([]runtime.MemStats, 4) does not escape
./tt.go:13: main &stats[0] does not escape
./tt.go:15: main func literal does not escape
./tt.go:43: main &stats[3] does not escape
./tt.go:48: main ... argument does not escape
Inner leaks 0, outer leaks 1
Inner leaks 0, outer leaks 0
Inner leaks 0, outer leaks 0
Inner leaks 0, outer leaks 0
I have three questions regarding this program:
1. Does it make sense to use the runtime functions in this way?
2. Why is there a “leak” in the first iteration and how do I debug it?
3. Why does the line “./tt.go:22: make(chan bool, 0) escapes to heap” show up twice?
Cheers,
Markus