Golang内存逃逸
内存逃逸
程序变量会携带一组校验数据,证明它的整个生命周期是否在运行时完全可知,通过校验就可以在 栈 分配,否则就说它逃逸,必须在 堆 上分配
如何查看内存逃逸
通过 go build -gcflags=-m 查看逃逸情况
常见内存逃逸
方法内把局部变量指针返回:局部变量本应在栈中分配,栈 中回收,返回时被外部引用,生命周期大于 栈,溢出
发送指针或带有指针的值到channel:不知道哪个goroutine会在channel接收数据,编译器不知道变量什么时候会被释放
切片存储指针或带指针的值:典型例子 []*string 尽管后面的数组可能是在 栈 上分配,但引用的值一定是在 堆 上
slice的背后数组被重新分配了,因为append时可能会超出其容量cap,slice初始化的地方在编译时会在 栈 上分配,扩充会在 堆 上分配
interface类型上调用方法,interface类型上调用方法都是动态调用的,方法实现在运行的时候才知道,io.Reader类型的变量r,存储上逃逸,堆 上分配
发送指针或带有指针的值到channel:不知道哪个goroutine会在channel接收数据,编译器不知道变量什么时候会被释放
切片存储指针或带指针的值:典型例子 []*string 尽管后面的数组可能是在 栈 上分配,但引用的值一定是在 堆 上
slice的背后数组被重新分配了,因为append时可能会超出其容量cap,slice初始化的地方在编译时会在 栈 上分配,扩充会在 堆 上分配
interface类型上调用方法,interface类型上调用方法都是动态调用的,方法实现在运行的时候才知道,io.Reader类型的变量r,存储上逃逸,堆 上分配

浙公网安备 33010602011771号