Content #
在传统的不带 GC 的编程语言中,我们需要关注对象的分配位置,要自己去选择对象是分配在堆还是栈上,但在 Go 这门有 GC 的语言中,集成了逃逸分析功能来帮助我们自动判断对象应该在堆上还是栈上,我们可以使用 go build -gcflags="-m" 来观察逃逸分析的结果:
package main
func main() {
var m = make([]int, 10240)
println(m[0])
}
较大的对象也会被放在堆上。
❯ go build -gcflags="-m" escape.go
# command-line-arguments
./escape.go:3:6: can inline main
./escape.go:4:14: make([]int, 10240) escapes to heap
这里,执行 gcflags=“-m” 的输出,我们就可以看到发生了逃逸。如果将m所需的空间修改为1024,将不会有逃逸发生,m会被分配在栈上。
若对象被分配在栈上,它的管理成本就比较低,我们通过挪动栈顶寄存器就可以实现对象的分配和释放。若对象被分配在堆上,我们就要经历层层的内存申请过程。但这些流程对用户都是透明的,在编写代码时我们并不需要在意它。只有需要优化时,我们才需要研究具体的逃逸分析规则。