目录
什么是逃逸分析?
Go程序为变量分配内存分为两途径:
1,全局的堆空间动态分配内存
2,每个goroutine的栈空间
一般来说开发者并不需要关心内存分配在栈上 or 还是堆上。但从性能的角度出发,在栈上分配内存和在堆上分配内存,性能差异还是非常大的。
在栈上分配和回收内存的开销很低,只需要2个CPU 指令:PUSH、POP。
前者是将数据push到栈空间以完成分配,后者则是释放空间,也就是说在栈上分配内存,消耗的仅是将数据拷贝到内存的时间,而在堆上分配,一个很大的额外开销则是垃圾回收。
在Go中,堆内存通过垃圾回收机制自动管理,Go的垃圾回收采用的是标记清除算法,并且在此基础上使用了三色标记法和写屏障技术,提高了效率。
标记清除算法的一个典型操作是在标记期间,需要STW,即暂停程序(Stop the world),标记结束之后,用户程序才可以继续执行。
堆内存分配导致垃圾回收的开销远大于栈空间分配与释放的开销。
那么 Go编译器怎么知道某个变量需要分配在栈 or 堆上呢?
编译器决定内存分配位置的方式,就称之为逃逸分析(escape analysis)。逃逸分析由编译器完成,作用于编译阶段。