失意--golang的逃逸分析学习笔记
逃逸分析有什么作用
c/c++毒药,go蜜糖。
c/c++内存是手动释放的,导致程序写代码的时候,程序员如履薄冰。
golang堆栈内存透明,golang将复杂的内存机制交给了编译器。
golang的逃逸分析将变量内存分配的该去的地方,局部变量优先分配到栈上,全局变量分配到堆上
如果变量都分配到堆上,堆不像栈那样会自动清理,会引起go的频繁垃圾回收,而垃圾回收会占用比较大的系统开销。
堆与栈的对比
堆适合不可预知大小的内存分配,但是为此付出的代价就是分配速度很慢,而且会造成内存碎片。栈分配内存只需要PUSH命令,并且会自动释放,而堆分配内存会找到一个合适大小的内存块,之后只能通过垃圾回收的机制来释放。
通过逃逸分析,可以尽量把那些不需要的变量分配到栈上,堆上的变量少了,会减少堆内存分配的开销,同事也会减少垃圾回收(GC)压力,提高程序运行速度。
逃逸分析是怎样完成的?
编译器分析代码的特征的时候和代码的周期,GO中的变量只有在编译器可以证明函数返回后变量没有被引用,才会分配到栈上,否则分配到堆上。
- 如果变量在函数外部没有被引用,则优先存在栈上(当定义局部变量一个很大的数组远超于栈的内存,则会分配在堆上)
- 如果变量在函数外部有引用,则优先分配到堆上

go build -gcflags -m -i main.go

结果
t局部变量返回以后还有其他函数使用到堆上可以理解,x也进行了内存逃逸(因为编译期间很难确定x的类型所以发生了内存逃逸)
Go与C/C++上面的堆栈是一个意思吗?
-
C/C++所提及的堆栈本质上操作系统层级的概念;
-
GO程序运行在操作系统的内存上,栈全部被GO语言所消耗,对于用户态GO它们所消耗的堆栈其实是GO管理向操作系统申请的堆内存,GO语言为了防止内存碎片化会适当的时候对整个栈进行深度拷贝,将其复制到另一个内存区域。

浙公网安备 33010602011771号