golang 内存逃逸

  • Post author:
  • Post category:golang

参考:Golang内存分配逃逸分析 – jimshi – 博客园

GO语言变量逃逸分析 – Go语言中文网 – Golang中文社区

总结下,就是:

1. 堆和栈

之前写c++的时候,栈是各种局部变量,函数结束就自动释放;堆就是使用new和malloc分配的,需要rd去关注啥时候分配,啥时候释放。在栈上分配内存比较快,而且回收也快,在堆上分配就耗费的资源比较多。而且,在栈上面分配的,函数结束后就自动回收了,只有全局的栈上的变量和堆上的变量,才需要GC回收,减少堆上分配内存的同时,也减轻了gc的压力。

所以go就希望,能尽可能多的在栈上面分配资源。那go是怎么做的呢?

func F() {
	temp := make([]int, 0, 20)
	...
}

就比如上面这种,虽然是手动执行了make来分配内存,正常来说应该在堆上,但是实际上是在栈上面。但是也不是所有的局部变量都能分配到栈上。

func F() []int{
	a := make([]int, 0, 20)
	return a
}

比如上面这种,虽然是局部变量,但是因为这个局部变量作为函数返回值返回了,所以也不能分配在栈上,必须分配在堆上。这就是内存逃逸。

2. 检查内存逃逸

指令:

go build -gcflags=-m

 执行的时间点:

编译的时候分析出来的,不是运行的时候

3.发生内存逃逸的几种情况

大体的原则就是,不确定要分配堆还是栈的时候,就分配到堆上,哈哈

(1)函数内分配的指针,作为函数返回值返回的时候

(2)栈空间不足的时候

package main

func Slice() {
    s := make([]int, 1000, 1000)

    for index, _ := range s {
        s[index] = index
    }
}

func main() {
    Slice()
}

比如上面这种,只是分配了1000的时候,还是在栈上分配,当调整为1000*10的时候,就分配到堆上了

(3)interface:当函数的入参是interface的时候 

(4)slice和map里面的元素时指针的时候

(5)闭包,这个没看懂


版权声明:本文为qq_32625545原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。