C++ 语言中,需要开发者自己学习如何进行内存分配,选用怎样的内存分配方式来适应不同的算法需求。比如,函数局部变量尽量使用栈,全局变量、结构体成员使用堆分配等。
Go语言将这个过程整合到了编译器中,命名为“变量逃逸分析”。通过编译器分析代码的特征和代码的生命周期,决定应该使用堆还是栈来进行内存分配。
逃逸分析
package mainimport "fmt"// 本函数测试入口参数和返回值情况func dummy(b int) int {// 声明一个变量c并赋值var c intc = breturn c}// 空函数, 什么也不做func void() {}func main() {// 声明a变量并打印var a int// 调用void()函数void()// 打印a变量的值和dummy()函数返回fmt.Println(a, dummy(0))}
go run -gcflags “-m -l” main.go
- -gcflags 参数是编译参数
- -m 表示进行内存分配分析,
- -l 表示避免程序内联,也就是避免进行程序优化
运行结果
command-line-arguments
./demo-04-变量逃逸.go:28:13: … argument does not escape ./demo-04-变量逃逸.go:28:13: a escapes to heap ./demo-04-变量逃逸.go:28:22: dummy(0) escapes to heap 0 0
- c 是整型,被复制并作为 dummy() 函数的返回值返回, c 在 dummy() 函数中分配的内存被释放
- 不会影响 main() 中使用 dummy() 返回的值
- 其值通过 dummy() 的返回值“逃出”了 dummy() 函数
