go 逃逸分析

Created

2024-10-28 13:21:57

Updated

2024-10-28 13:22:04

Tip

看过汇编后, 我们知道,在栈上的局部变量在函数返回后,会被释放,如果变量还会被引用到,那么就不能在栈上分配,编译器会将它设置为在堆上分配内存

1 分析方法

item description
-m 打印逃逸分析信息
xxx escapes to heap 当前变量的一个副本拷贝在堆上进行分配
moved to heap: xxx 表示变量自身在堆上进行分配
leaking param content: xxx 表示如果这个变量为指针的话,则是其指向的内容在堆上分配
package main

import (
    "unsafe"
)
// 是否在堆中
//
//go:linkname inheap runtime.inheap
func inheap(arg uintptr) bool

// 是否在栈或堆中
//
//go:linkname inHeapOrStack runtime.inHeapOrStack
func inHeapOrStack(b uintptr) bool
func main() {
    var a int = 1
    // false 表示在栈上
    println(inheap(uintptr(unsafe.Pointer(&a))))
}
go run -gcflags "-m -l" main.go

2 例子

2.1 返回指针

package main

func test() *int {
    a := 66 // 逃逸到堆上
    return &a
}

func main() {
    println(test())
}
go run -gcflags "-m -l" main.go
    ./main.go:4:2: moved to heap: a
    0xc00001c1a8
Back to top