go语言内存逃逸场景分析

2022/05/06 go

内存逃逸是由编译器来决定内存分配的位置(是在栈上还是在堆上分配内存),而不是由程序员来决定的! 在函数中申请一个新的对象:

1、如果分配在栈中,则函数执行结束后可自行将内存回收
2、如果分配在堆中,则函数执行结束后可交给GC(垃圾回收)处理。

内存逃逸场景

1、指针逃逸

我们知道Go可以返回局部变量指针,这其实是一个典型的变量逃逸案例。

type Student struct {
	Name string
}

func Say() *Student {
	stu := Student{}
	stu.Name = "张三"
	return &stu
}

ppwnhE6.png

2、栈空间不足逃逸

很多函数的参数为interface 类型,比如 fmt.Println(a ...interface{}),编译期间很难确定其参数的具体类型,也会产生逃逸

func slice() {
	s := make([]int, 10000, 10000)

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

ppwnjVP.png

3、动态类型逃逸

s := "sbc"
fmt.Println(s)

ppwuEV0.png

4、闭包引用对象逃逸

func bibao() func() int {
	a, b := 0, 1

	return func() int {
		a, b = b, a+b
		return a
	}
}

该函数返回一个闭包,闭包引用了函数的局部变量a和b,使用时通过该函数获取闭包,a,b只能放到堆中,所以产生了逃逸。

ppwunGF.png

小结:

栈上分配内存比在堆中分配内存有更高的效率;
栈上分配的内存不需要GC处理;
逃逸分析的目的是决定分配地址是栈还是堆;
逃逸分析在编译阶段完成;

Search

    Table of Contents