You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:57:02