go语言-变量逃逸

go变量逃逸

go语言的一个变量是在堆上分配,还是在栈上分配,是经过golang编译器的逃逸分析之后得出结论的,这一切都是编译器帮我们完成的。

什么是变量逃逸

简单来说,变量逃逸就是一个变量由栈逃逸到堆的过程。
我们知道c和c++变量的内存分配和销毁都是需要程序员手动来执行的。
举个栗子,在函数内部定义了一个局部变量,然后返回这个局部变量的地址,这些局部变量是在栈上分配的(静态分配内存),一旦函数执行完成,变量占据的内存被销毁,任何这个返回值的动作,比如解引用,都会扰乱程序的执行,甚至导致程序崩溃。
或者,我们使用new函数构造一个变量(动态分配内存),然后返回变量的地址,因为变量是在堆上创建的,所以函数执行完成退出时变量不会被销毁。但是调用者很可能忘记delete,也就会发生内存泄露。
综上,变量的逃逸分析就是决定一个变量是分配在堆上还是栈上。

为什么要逃逸分析

逃逸分析是为了合理的分配变量到它该去的地方,如果一个变量在函数执行完成后没有别的用处,那么就该分配到栈上,毕竟栈上的内存分配比堆上的快很多,相反,如果变量在函数结束后还有其他引用,那就该分配到堆上。
当然,如果变量都分配到堆上,堆不像栈可以自动清理,堆会引起go频繁的进行垃圾回收,而垃圾回收会占用比较大的系统开销。堆和栈相比,堆适合不可预知大小的内存分配,但分配速度较慢,而且会形成内存碎片,最后还需要gc进行释放。栈内存分配就比较快了,只需要CPU的两个命令即可实现分配和释放。
通过逃逸分析,可以尽量把哪些不需要分配到堆上的变量直接分配到栈上,堆上的变量减少了,会减轻分配堆内存的开销,同时也会减少gc的压力,提供程序的运行速度。

编译器的逃逸分析

go编译器逃逸分析的基本原则是,若个一个函数返回对一个变量的引用,那么它就会发生逃逸。如果编译器对代码进行分析后,发现函数返回后,变量不在被引用,那么还是分配到栈上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章