逃逸分析有什么作用
前面讲的 C/C++ 中出现的问题,在 Go 语言中却作为一个语言特性被大力推崇,真是 C/C++ 之 “毒药” Go 之 “蜜糖”。
C/C++ 中动态分配的内存需要手动释放,导致程序员在写代码时,如履薄冰。这样做也有它的好处:程序员可以完全掌控内存。但是缺点也是很多的,例如经常忘记释放内存,导致内存泄漏。 为此,很多现代语言都包含了垃圾回收机制。
Go 的垃圾回收,让堆和栈对程序员保持透明。真正解放了程序员的双手,让他们可以专注于业务,“高效” 地完成代码编写,而把那些内存管理的复杂机制交给编译器。
逃逸分析把变量合理地分配到它该去的地方,“找准自己的位置”。即使是用 new 函数申请到的内存,如果编译器发现这块内存在退出函数后就没有使用了,那就分配到栈上,毕竟栈上的内存分配比堆上快很多;反之,即使表面上只是一个普通的变量,但是经过编译器的逃逸分析后发现, 在函数之外还有其他的地方在引用,那就分配到堆上。真正地做到 “按需分配”。
如果变量都分配到堆上,堆不像栈可以自动清理。就会引起 Go 频繁地进行垃圾回收,而垃圾回收会占用比较大的系统开销。
堆和栈相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片;栈内存分配则会非常快。 栈分配内存只需要通过 PUSH 指令,并且会被自动释放;而堆分配内存首先需要去找到一个大小合适的内存块,之后要通过垃圾回收才能释放。
通过逃逸分析,可以尽量把那些不需要分配到堆上的变量直接分配到栈上,堆上的变量少了, 会减轻堆内存分配的开销,同时也会减少垃圾回收(Garbage Collection,GC)的压力,提高程序的运行速度。
上次更新: 5/9/2023, 10:58:32 AM