堆与栈的区别,程序使用内存区域划分

简述

内存区域划分是比较重要但也常令人忽视,我也是最近才比较清晰,记录一下。

程序使用内存划分

一个程序占用的内存分为以下几个部分:
1、全局区(静态区)(static)
全局变量和静态变量存储的区域,程序结束后由系统自动释放。
2、常量区
常量存储的区域,程序结束后系统自动释放。
3、堆区(heap)
一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收(对于Java、C#而言)。
4、栈区(stack)
由编译器自动分配释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。
5、程序代码区
存放函数体二进制代码的区域。

堆和栈的异同

1、申请方式
栈由系统自动分配;
堆需要程序员自己申请,并指明大小。如C中的malloc函数,C++中new运算符,注意指针本身在栈中,只是通过malloc和new分配的空间是在堆中的。
2、系统分配方式
栈–只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则报栈溢出异常提示;
堆–系统收到程序申请,会遍历操作系统空间内存地址链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点空间分配给程序。系统在这块内存的首地址处记录本次分配大小,以便delete语句释放内存空间,系统会自动将节点多余的那部分重新放入空闲链表中。
3、申请大小限制
栈是一块连续的内存区域,windows下栈的大小是2M,如果申请空间超过栈的剩余空间,将提示溢出。
堆是系统使用链表连存储的空闲内存地址形成的不连续内存区域。堆的大小受限于计算机系统中有效虚拟内存。堆获得的空间比较灵活,也比较大。
4、申请效率
栈是系统自动分配,速度快。
堆是new分配的内存,最好是用VirtualAlloc分配虚拟内存。
5、堆和栈的存储内容
栈–函数调用时,第一个进栈的是主函数中的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,然后是函数中的局部变量。(静态变量是不入栈的);当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令。
堆–在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。

猜你喜欢

转载自blog.csdn.net/lusanshui/article/details/84949867