逃逸分析
逃逸分析怎么完成的
Go 语言逃逸分析最基本的原则是:如果一个函数返回对一个变量的引用,那么这个变量就会 发生逃逸。 编译器会分析代码的特征和代码的生命周期,Go 中的变量只有在编译器可以证明在函数返回 后不会再被引用的,才分配到栈上,其他情况下都是分配到堆上。 Go 语言里没有一个关键字或者函数可以直接让变量被编译器分配到堆上。相反,编译器通过 分析代码来决定将变量分配到何处。 对一个变量取地址,可能会被分配到堆上。但是编译器进行逃逸分析后,如果考虑到在函数返 回后,此变量不会被引用,那么还是会被分配到栈上。简单来说,编译器会根据变量是否被外部引 用来决定是否逃逸: 1)如果变量在函数外部没有引用,则优先放到栈上。 2)如果变量在函数外部存在引用,则必定放到堆上。 针对第一条,放到堆上的情形:定义了一个很大的数组,需要申请的内存过大,超过了栈的存 储能力。
如何确认逃逸发生
package main
import "fmt"
func foo() *int {
t := 3
return &t
}
func main() {
x := foo()
fmt.Println(*x)
}
以下命令 go build -gcflags '-m -l' main.go 返回以下结果
# command-line-arguments
./main.go:6:2: moved to heap: t
./main.go:11:13: ... argument does not escape
./main.go:11:14: *x escapes to heap
内存逃逸的几种情况
1、函数返回一个指针,这个指针指向一个局部变量。 2、切片,map作为返回值时 3、切片,map里保存指针类型元素 4、指针类型变量作为返回值 5、函数闭包 6、channel里包含指针类型元素