Go语言值是否存储在栈上?Example结构体实例内存分配位置咨询
Go 栈堆分配规则及示例代码解答
核心前提
Go 不存在语法层面的「变量必须分配在栈/堆」的规定,具体分配位置完全由编译器的逃逸分析结果决定:只要编译器能证明变量在函数退出后不会被外部引用,就会把它分配在当前函数的栈帧上;反之只要存在逃逸行为(被外部引用、跨 goroutine 访问、被闭包捕获后在函数外使用等),就会分配到堆上由 GC 负责回收。
你给出的代码说明
首先纠正你代码里的语法错误:new 关键字的入参是类型而非值,且 new 返回对应类型的指针,所以第二行的正确写法应为 var ex *Example = &Example{10} 或 var ex *Example = new(Example); ex.field_a = 10。
针对两种声明的分配情况,分两种场景判断:
- 如果变量是函数内部的局部变量,且没有任何逃逸行为:
var ex Example = Example{10}会直接分配在栈上,函数退出时随栈帧回收直接释放- 修正后的指针声明
var ex *Example = &Example{10}也会被优化为栈分配,指针指向栈上的结构体实例,不会触发堆分配
- 如果变量存在逃逸行为(比如是全局变量、指针被作为函数返回值返回、被其他 goroutine 引用、被闭包捕获后在函数外执行):
无论你用哪种写法声明变量,都会被编译器分配到堆上。
验证分配位置的方法
你可以在编译代码时添加 gcflags 参数查看逃逸分析结果:
go build -gcflags="-m" your_file.go
编译器会直接输出每个变量的逃逸情况,明确标注是分配在栈还是堆。
内容的提问来源于stack exchange,提问作者Vlad Varvashenko
相关产品推荐
相关产品推荐

