知道golang的內存逃逸嗎?什麼狀況下會發生內存逃逸?golang
golang程序變量
會攜帶有一組校驗數據,用來證實它的整個生命週期是否在運行時徹底可知。若是變量經過了這些校驗,它就能夠在棧上
分配。不然就說它 逃逸
了,必須在堆上分配
。面試
能引發變量逃逸到堆上的典型狀況:數組
go build -gcflags=-m
查看逃逸的狀況。package main import "fmt" type A struct { s string } // 這是上面提到的 "在方法內把局部變量指針返回" 的狀況 func foo(s string) *A { a := new(A) a.s = s return a //返回局部變量a,在C語言中妥妥野指針,但在go則ok,但a會逃逸到堆 } func main() { a := foo("hello") b := a.s + " world" c := b + "!" fmt.Println(c) } 複製代碼
執行go build -gcflags=-m main.go
markdown
go build -gcflags=-m main.go # command-line-arguments ./main.go:7:6: can inline foo ./main.go:13:10: inlining call to foo ./main.go:16:13: inlining call to fmt.Println /var/folders/45/qx9lfw2s2zzgvhzg3mtzkwzc0000gn/T/go-build409982591/b001/_gomod_.go:6:6: can inline init.0 ./main.go:7:10: leaking param: s ./main.go:8:10: new(A) escapes to heap ./main.go:16:13: io.Writer(os.Stdout) escapes to heap ./main.go:16:13: c escapes to heap ./main.go:15:9: b + "!" escapes to heap ./main.go:13:10: main new(A) does not escape ./main.go:14:11: main a.s + " world" does not escape ./main.go:16:13: main []interface {} literal does not escape <autogenerated>:1: os.(*File).close .this does not escape 複製代碼
./main.go:8:10: new(A) escapes to heap
說明 new(A)
逃逸了,符合上述提到的常見狀況中的第一種。app
./main.go:14:11: main a.s + " world" does not escape
說明 b
變量沒有逃逸,由於它只在方法內存在,會在方法結束時被回收。oop
./main.go:15:9: b + "!" escapes to heap
說明 c
變量逃逸,經過fmt.Println(a ...interface{})
打印的變量,都會發生逃逸,感興趣的朋友能夠去查查爲何。學習
以上操做其實就叫逃逸分析。下篇文章,跟你們聊聊怎麼用一個比較trick的方法使變量不逃逸。方便你們在面試官面前秀一波。ui
中文、數字、英文字母
的字符串