转自:https://zhuanlan.zhihu.com/p/59751716
原作者github:https://github.com/lvgithub/go_blog/blob/master/Escape/Escape.md
函数传递指针还是传值?
两种选择的本质区别是什么?
哪种方式的性能更高呢?
先说结论:不一定
逃逸分析
Go中有一个很重要的概念就是逃逸分析。
逃逸分析是指由编译器决定内存分配的位置。
- 分配在栈上:函数运行结束后自动回收
- 分配在堆上:函数运行结束后由GC回收
最终执行效率和这两种分配规则有重要联系。
分析
直观上看,传指针不涉及值拷贝,效率肯定更高,但是实际情况是传指针会导致变量逃逸到堆上,这会增加GC的负担,而且在堆上分配内存会比在栈上分配内存效率更低。
如果传递的变量比较小,拷贝造成的负担小于逃逸的负担(分配堆内存+GC),那么就会降低整体的效率。
栈上的值:分配内存效率高,减少了GC的压力,但是要维护多个副本
堆上的值:分配内存效率低,增加了GC的压力,但是只需要维护一个值
什么情况下会发生逃逸
- 共享了栈上的值
- 栈空间不足(比如创建一个超大的slice,超过了栈的空间)
- 动态类型逃逸,函数参数为interface类型(经典的fmt.Println方法)
- 闭包引用对象,其本质还是共享了栈上的值