知道golang的内存逃逸吗?什么情况下会发生内存逃逸?
因为函数都是运行在栈上的,在栈声明临时变量分配内存,函数运行完毕再回收该段栈空间,并且每个函数的栈空间都是独立的,其他代码都是不可访问的。但是在某些情况下,栈上的空间需要在
该函数被释放后依旧能访问到,这时候就涉及到内存的逃逸了。
能引起变量逃逸到堆上的典型情况:
type S struct { s string } func getS(str string) *S { return &S{str} } a := getS("hello") b := a.s + " world" c := b + "!" fmt.Println(c)执行go build -gcflags=-m main.go
./main.go:11:6: can inline getS ./main.go:16:11: inlining call to getS ./main.go:19:13: inlining call to fmt.Println ./main.go:11:11: leaking param: str ./main.go:12:9: &S literal escapes to heap 局部变量return逃逸 符合情况 ./main.go:16:11: &S literal does not escape 这里是a拿到了&S 局部变量 不逃逸 ./main.go:17:11: a.s + " world" does not escape 局部变量不逃逸 ./main.go:18:9: b + "!" escapes to heap c变量逃逸 ./main.go:19:13: c escapes to heap ./main.go:19:13: []interface {} literal does not escape
ch := make(chan *int, 1) a := 10 b := &a go func() { ch <- b }() go func() { select { case <-ch: return default: } }() time.Sleep(2 * time.Second)执行go build -gcflags=-m main.go
./main.go:22:5: can inline main.func1 ./main.go:20:2: moved to heap: a ./main.go:22:5: func literal escapes to heap ./main.go:25:5: func literal escapes to heap
s := make([]*string, 10) a := "aaaaaa" s[0] = &a执行go build -gcflags=-m main.go
./main.go:11:6: can inline main ./main.go:33:2: moved to heap: a 变量发生逃逸 ./main.go:32:11: make([]*string, 10) does not escape