最详细的堆和栈的区别

本文详细对比了堆和栈在管理方式、生长方向、空间大小、分配方式、分配效率、内存碎片问题、存储内容及分配后系统响应等八个方面的不同,深入解析两者在程序设计中的应用特点。

这个问题,经常会被面试官问到,所以我总结了一下堆和栈的区别,我是从8个方面进行对其分析:

1.管理方式:栈是由编译器进行管理的,而堆是由程序员自己对其管理的,使用比较方便,但是容易产生内存泄漏。

2.生长方向:栈是由高地址向低地址方向生长,是一段连续的内存区域,而堆是由低地址向高地址方向生长,是一段不连续的内存区域,是由链表进行对其遍历的。

3.空间大小:栈顶地址和栈的最大容量由系统预先规定(通常默认2M或10M,Linux中可以通过ulimit -s 命令对其修改,修改之后会增加内存开销和启动时间);堆的大小则受限于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G左右的空间。

4.分配方式:栈是由编译器进行分配的,主要有两种分配方式:静态分配和动态分配,静态分配是有编译器完成的,如:局部变量,而动态分配是malloc在申请空间,用完之后自动释放。而堆只能动态开辟由程序员进行释放。

5.分配效率:栈由计算机底层提供支持,分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,因此效率较高。堆由函数库提供,机制复杂,效率比栈低得多。

6.内存碎片问题:栈不会产生内存碎片的,因为栈是先进后出的队列,内存块弹出栈之前,在其上面的后进的栈内容已弹出。而频繁的申请和释放堆空间,则会导致堆空间的不连续,因此会产生大量的内存碎片,导致程序的效率低。

7.存储内容:栈在函数调用时,首先压入调用函数中下条指令(函数调用语句的下条可执行语句)的地址,然后是函数实参,然后是被调函数的局部变量。本次调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的指令地址,程序由该点继续运行下条可执行语句。堆通常在头部用一个字节存放其大小,堆用于存储生存期与函数调用无关的数据,具体内容由程序员安排。

8.分配后系统的响应:对栈而言:只要栈的剩余空间大于所申请空间,系统则会为它正常提供内存,否则,则会报告异常提示栈溢出。对堆而言:操作系统为堆维护一个纪录空闲内存的链表,当程序员需要申请空间时,操作系统就会对其进行遍历,找到第一个大于用户所申请的堆节点,然后将该节点从空闲内存链表中删除,并将该节点内存空间分配给程序,若没有足够大小的空间(可能由于内存碎片太多),然后操作系统就有可能调用系统功能去增加程序数据段的内存空间,以便有机会分到足够大小的内存,然后进行返回,大多数系统会在该内存空间首地址处记录本次分配的内存大小,供后续的释放函数(如free/delete)正确释放本内存空间。

   以上就是我所总结的堆和栈的区别,如有错误请指正!!!各位同仁如果还能总结出其他区别。请评论区留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值