讲讲堆内存和栈内存
前段时间面试腾讯时候,面试官问了一个很基础的问题:请你说说堆内存和栈内存的区别?
我:基本就是那套模板,例如栈内存是由编译器自动分配和释放,其内存地址在编译期已确定的;主要用来存储局部变量,函数参数以及函数调用的地址等等;对于堆内存来说,其生命周期是由程序员决定的,即程序员手动申请释放,如果没有及时释放,就会造成内存泄漏,当程序结束时,会有操作系统回收未释放的内存。
说完之后,面试官没有立即反应,我以为他不太满意,又接着说了说堆栈的增长方向和内存大小等等…
不知道是我回答的不好还是面试官太高冷,没什么说辞…
本文内容有参考百科,知乎,博客等优秀回答。
1. 从编程语言角度理解不同内存
程序的内存分配:
一个由C/C++编译的程序占用的内存分布:
栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等
堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收
全局区(global)/ 静态区(static):
- data区:已经初始化的全局变量、静态变量和常量
- bss区:用来存放程序中未初始化的全局变量和静态变量;程序执行前BSS段会自动清0。
- 常量区:全局区中划分的一个小区域,里面存放的是常量,如const修饰的全局变量、字符串常量
代码区(code):存放函数体的二进制代码
1 | /* |
2. 从物理层角度理解堆栈内存
不知道大家有没有这样的想法,堆栈不就是内存的不同区,为什么访问速度会有差矣呢?
最近想到了这个问题,但奈何才疏学浅,只能在各种论坛搜索资料。
- 从硬件上来说,堆和栈最终都是内存条上的若干存储单元,理应并没有什么不同
- 但是很多CPU对压栈,出栈操作有硬件(指令)上的支持,所以在栈区分配/归还内存速度较快;尤其是函数内部的局部变量,可以轻易与函数调用/返回绑定
- 由于栈内存分配/回收的特殊机制,使得同一函数内部的”局部变量”总是分配在一段连续的内存空间上