一、概述

        golang 内存分配的位置由编译决定,不像c或c++ 使用malloc/new 就能在堆上分配内存。内存逃逸是指:当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。

二、golang内存分配基本原则
  • 当函数外部对指针没有引用时,优先分配在上。
  • 当函数外部对指针存在引用时,优先分配在上。
  • 当函数内分配一个较大对象时,优先分配在上。
三、golang如何内存逃逸分析

在go build 时加上-gcflags "-m",就会对所有函数中的所有对象进行内存逃逸分析,分析结果直接显示在终端上。

四、为什么进行内存逃逸分析

1.分配在堆上:分配与释放操作都存在较大开销,可能出现内存碎片,且过多的内存分配在堆上会加重GC负担。

2.分配在栈上:cpu只需要简单的“PUSH”和“RELEASE”指令即可完成内存的分配与释放。

五、go几种内存逃逸场景

1.指针逃逸:对象i被分配到堆上。

package main

func test() *int {
	i := 0
	return &i
}

func main() {
	test()
}

        

2.大对象分配: s被分配到栈上

package main

func stack() {
	s := make([]int, 100000, 100000)
	s[0] = 1
}

func main() {
	stack()
}

3.动态类型逃逸

package main

func dynamic() interface{} {
	i := 0
	return i
}

func main() {
	dynamic()
}

4.闭包逃逸:a、b 都逃到堆上

package main

import "fmt"

func fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b+a, a+b
		return a
	}
}

func main() {
	f := fibonacci()
	fmt.Println(f())
	fmt.Println(f())
}
参考文献