Golang中的内存逃逸分析

什么是内存逃逸?

本该在栈上分配空间的变量因为一些特别的原因,导致该变量最终在堆上分配空间,导致变量逃逸

内存逃逸的一些场景分析

1.闭包导致的内存逃逸:

在函数运行栈空间上分配的内存,由于闭包的关系,变量在函数的作用域之外使用

func closure() func() int {
    var a int
    return func() int {
        a++
        return a
    }
}

2.返回指向栈变量的指针:

返回的变量是栈对象的指针,编译器认为该对象在函数结束之后还需要使用

type Empty struct {}
func Demo() *Empty  {
    return &Empty{}
}

3.申请大空间或者可变长空间导致的内存逃逸

申请的空间过大,也会直接在堆上分配空间/编译器无法知道需要分配多大的空间

4.返回局部引用也会导致

编译器认为返回的对象可能会在函数调用完成之后, 还会再次使用 所以, 编译器会在堆上分配内存空间

func returnMap() map[string] struct {} {
    return  make(map[string]struct{})
}
func returnSlice() [] int {
    return make([]int,10)
}

总结:

逃逸是在编译期间完成的,主要是决定是在栈中或者堆中分配内存,在实际分析中通过go build -gcflags=-m main.go命令可以发现内存是否逃逸

原文地址:https://www.cnblogs.com/peterleee/p/14247161.html