一架梯子,一头程序猿,仰望星空!
Golang中级特性面试题 > 内容正文

Golang局部变量分配在栈上还是堆上?


问题简答

一般来说,局部变量是分配在栈内存空间上,函数返回后就释放对应的栈内存空间,但是有些特殊的局部变量则是分配在堆内存上,例如:指针类型、引用类型。

问题详解:

堆内存和栈内存

根据内存管理(分配和回收)方式的不同,可以将内存分为 堆内存 和 栈内存。

  • 堆内存:由内存分配器和垃圾收集器负责回收
  • 栈内存:由编译器自动进行分配和释放

一个程序运行过程中,也许会有多个栈内存,但肯定只会有一个堆内存。

每个栈内存都是由线程或者协程独立占有,因此从栈中分配内存不需要加锁,并且栈内存在函数结束后会自动回收,性能相对堆内存好要高。

而堆内存呢?由于多个线程或者协程都有可能同时从堆中申请内存,因此在堆中申请内存需要加锁,避免造成冲突,并且堆内存在函数结束后,需要 GC (垃圾回收)的介入参与,如果有大量的 GC 操作,将会吏程序性能下降得历害。

局部变量是从哪里分配的?

在函数里声明定义的变量,我们称之为局部变量。

一般来说,局部变量是分配在栈内存空间上,函数返回后就释放对应的栈内存空间。

但是有些特殊的局部变量则是分配在堆内存上,例如:指针类型、引用类型

这种局部变量,虽然在函数里声明定义,但是在函数外还会持续的使用。

对于这类局部变量,显然我们是不希望函数退出后将其销毁的。

那怎么办呢?可以从堆区分配内存空间给这类局部变量。