逃逸分析

逃逸分析

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会被分配在栈上。

若对象被分配在栈上,它的管理成本就比较低,我们通过挪动栈顶寄存器就可以实现对象的分配和释放。若对象被分配在堆上,我们就要经历层层的内存申请过程。但这些流程对用户都是透明的,在编写代码时我们并不需要在意它。只有需要优化时,我们才需要研究具体的逃逸分析规则。

Viewpoint #

From #

大咖助阵|曹春晖:聊聊 Go 语言的 GC 实现