剖析使Go语言高效的5个特性(3/5): 垃圾回收机制

翻译原文连接 转帖/转载请注明出处算法

英文原文连接 发表于2014/06/07安全

垃圾回收机制(Garbage Collection)

Go语言由于强制的内存垃圾回收机制变得更加简单和安全。但这并不意味着垃圾回收机制把Go程序变慢了,或者说垃圾回收机制最终决定了你程序的速度。不能否认,在堆(heap)上分配内存是有代价的。每次垃圾回收机制触发都会消耗必定的CPU。除非内存都被释放了,这些开销是不可避免的。函数

可是还有另一个地方咱们能够用来分配内存。那就是栈(stack)。post

图片描述

与C语言不一样,Go语言不须要你选择一个变量是分配在堆上(经过malloc),仍是栈上(经过将这个变量定义成函数内的局部变量)。Go语言实现了一个叫作逃逸分析(Escape Analysis)的优化技术。优化

图片描述

逃逸分析可以判断是否有任何对函数局部变量的引用在此函数以外也被用到了。若是没有引用在函数以外被用到,那么这个局部变量就能够安全地存储在栈上。在栈上存储的变量不须要特别的分配和释放操做。让咱们来看看下面这个例子:spa

图片描述

Sum函数把1到100之间的数字相加并返回结果。咱们一般不会这么来写这个函数,只是用它来展现逃逸分析算法。.net

由于numbers变量只在Sum函数里被引用,编译器会将这100整数存储在栈上而不是堆上。因此也就不须要去垃圾回收numbers变量,它会在Sum函数返回的时候自动被释放掉。翻译

图片描述

上面显示的第二个例子也是为了阐述一样的问题而创造出来的。在CenterCursor函数里,咱们建立了一个新的Cursor结构而且把它的指针保存在变量c里。而后咱们将变量c传入Center()函数。Center()函数将Cursor结构平移半个屏幕的距离。最后把Cursor结构的X和Y的坐标打印出来。虽然变量c是经过new函数分配的,它不会被存储在堆上。这是由于变量c的引用并无在CenterCursor函数以外被用到。指针

Go语言的优化在缺省设置下老是被打开的。你能够用-gcflags=-m参数来查看编译器的逃逸分析和内联决定。code

图片描述

逃逸分析是在编译时而不是运行的时候作的。不管垃圾回收机制多么高效,栈的分配老是比堆的分配要快。接下来,我还会讨论到栈。

相关文章
相关标签/搜索