# command-line-arguments src/main.go:7:9: &t escapes to heap src/main.go:6:7: moved to heap: t src/main.go:12:14: *x escapes to heap src/main.go:12:13: main ... argument does not escape
type Data struct { data map[int]int slice []int ch chan int inf interface{} p *int } func main() { d1 := Data{} d1.data = make(map[int]int) // GOOD: does not escape d1.slice = make([]int, 4) // GOOD: does not escape d1.ch = make(chan int, 4) // GOOD: does not escape d1.inf = 3// GOOD: does not escape d1.p = new(int) // GOOD: does not escape d2 := new(Data) // d2 是指针变量, 下面为该指针变量中的指针成员赋值 d2.data = make(map[int]int) // BAD: escape to heap d2.slice = make([]int, 4) // BAD: escape to heap d2.ch = make(chan int, 4) // BAD: escape to heap d2.inf = 3// BAD: escape to heap d2.p = new(int) // BAD: escape to heap }
interface
只要使用了 Interface 类型(不是 interafce{}),那么赋值给它的变量一定会逃逸
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
type Iface interface { Dummy() } type Integer int func (i Integer) Dummy() {} func main() { var ( iface Iface i Integer ) iface = i iface.Dummy() // make i escape to heap // 形成 iface.Dummy.i = i }
channel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
func test() { var ( chInteger = make(chan *int) chMap = make(chan map[int]int) chSlice = make(chan []int) chInterface = make(chan interface{}) a, b, c, d = 0, map[int]int{}, []int{}, 32 ) chInteger <- &a // 逃逸 chMap <- b // 逃逸 chSlice <- c // 逃逸 chInterface <- d // 逃逸 }
main.go:8:6: can inline (*User).SetRoles main.go:12:6: can inline SetRoles main.go:17:6: can inline main main.go:20:15: inlining call to SetRoles main.go:8:25: leaking param: roles main.go:8:7: (*User).SetRoles u does not escape main.go:12:15: leaking param: u to result ~r2 level=0 main.go:12:23: leaking param: roles to result ~r2 level=0 main.go:20:27: main []string literal does not escape main.go:20:2: a declared and not used
第二种逃逸,第二种开销会比较大
1 2 3 4 5 6 7 8 9 10 11 12 13
第二种 b.SetRoles([]string{"1", "2"})
main.go:8:6: can inline (*User).SetRoles main.go:12:6: can inline SetRoles main.go:17:6: can inline main main.go:22:12: inlining call to (*User).SetRoles main.go:8:25: leaking param: roles main.go:8:7: (*User).SetRoles u does not escape main.go:12:15: leaking param: u to result ~r2 level=0 main.go:12:23: leaking param: roles to result ~r2 level=0 main.go:22:21: []string literal escapes to heap main.go:22:3: main b does not escape