After doing several escape analysis tests, I have come across something that I cannot wrap my head around. Given the ultra simple code, why does Age supposedly escape to the heap:
package main
import "fmt"
type Person2 struct {
Age int
}
func (p *Person2) Dump() {
fmt.Println(p.Age)
}
func main() {
person := Person2{
Age: 99,
}
person.Dump()
}
Running:
go run -gcflags="-m" ./mem2/main2.go
Returns:
mem2/main2.go:9:6: can inline (*Person2).Dump
mem2/main2.go:10:13: inlining call to fmt.Println
mem2/main2.go:17:13: inlining call to (*Person2).Dump
mem2/main2.go:17:13: inlining call to fmt.Println
mem2/main2.go:9:7: p does not escape
mem2/main2.go:10:13: ... argument does not escape
>>> mem2/main2.go:10:15: p.Age escapes to heap <<<
mem2/main2.go:17:13: ... argument does not escape
mem2/main2.go:17:13: p.Age escapes to heap
I have added >>>, <<< to show the line of interest. This is a “primitive” struct with only 1 primitive type, initialised and handled in such a way as to avoid the heap. So why is Age escaped to the heap. Calling Dump by value instead of reference also makes no difference to the analysis.
How do I read this, for it says it escapes and I assume that the very next line says, it does not escape?