逃逸分析是指由编译器决定内存分配到堆上还是栈上。当我们在函数中申请了一个新的对象:
- 如果分配到栈中,则函数执行结束后可自动将内存回收。
- 如果分配到堆中,则函数执行结束后,不会自动将内存释放掉,需要GC在进行清除。
逃逸分析使Go语言能够将局部变量返回,程序员不需要担心局部变量分配到栈上还是堆上。并且Go程序员不需要像C程序员一样,担心内存泄漏的问题。
逃逸策略:
在函数中申请一个新的对象时,编译器会根据该对象是否被函数外部引用来确定是否逃逸。
- 如果变量在函数外部没有引用,则优先放到栈上。
- 如果变量在函数外部存在引用,则必定放到堆上。
注意,对于一个仅在函数内部使用的变量,也有可能放到堆上,比如内存过大超过栈的存储能力。我们很难通过肉眼直接判断函数内部的变量是否发生了逃逸,我们需要借助go build -gcflags=-m指令判断是否发生逃逸分析。
逃逸场景:
1.函数返回指针,会发生指针逃逸。如果我们的返回的结构体中包含指针,也会发生逃逸,比如slice、 map。
func main() {
getNum()
}
func getNum() *int {
i := 1
return &i
}
# ExpertProgramming/chapter04/escape/move_to_heap
./main.go:6:6: can inline getNum
./main.go:3:6: can inline main
./main.go:4:8: inlining call to getNum
./main.go:7:2: moved to heap: i
2.栈空间不足以存放当前创建的对象时,会将新创建的对象分配到堆上,发生逃逸。

最低0.47元/天 解锁文章
1187

被折叠的 条评论
为什么被折叠?



