堆与栈 内存分配

一、内存分配问题

1.从静态存贮区域分配,内存在编译的时候已经分配好,这个内存在整个程序运行阶段都存在。

2.从栈上创建,执行函数时,函数内的局部变量被分配到栈中,函数执行结束时自动释放,这些内存空间配置于处理器的指令集中,效率高而灵活,但是内存容量有限

3.从堆上创建,也成为动态内存分配,需要程序猿用malloc或者new来申请任意多少的内存空间(小于可用物理内存),函数执行完后也需要程序员自己进行free或者delete的操作来释放内存,其特点是动态内存的生命周期有我们将决定,使用非常灵活,但问题也比较多


二、堆与栈

1、申请方式

  栈:无需申请,创建时系统自动分配,例如,声明一个变量 int b;系统自动在栈中分配内存空间,,又例如,调用函数时,需要保存的变量。这种尤其是在递归调用时候,系统会分配一个栈的空间,后进先出,而后又由系统自动释放空间,不会造成内存泄露。

 堆:需要程序员自己申请,C中用malloc,java中用new,并指出的大小。先进先出、后进后出。在调用结束后,C中需要程序员自己释放,否则易造成内存泄露,而java的内存回收机制存在一定作用,但有可能仍发生内存泄露(短周期的对象被长周期的对象引用)。因为内存泄露的问题,导致软件越用越慢,重启后恢复快速运行


2、申请后系统的相应

 栈: 只要栈的剩余  空间大于申请空间,系统就会为其分配栈空间,否则就会报异常--栈溢出。

 堆:首先应该知道,操作系统中会有一个记录空闲区间的链表,当系统受到空间非配的申请时,就会遍历该链表,寻找第一个空间大于申请空间的堆结点,然后将该结点从链表中删除,并肩该空间非配给申请,。另外对于大多数熊,,这块内存空间的首地址会记录本次分配的大小,这样,代码中的free或者delete语句才能正确的释放该块空间。最后由于找到的堆结点的空间大小不会正好等于所申请空间的大小,因此会将剩余的空间的那部分重新放入空闲链表中


3、申请大小的限制

 栈:在window下,栈是向低地址扩展的数据结构,是一块连续的内存区域,这句话的意思是栈顶的地址和栈的容量是系统预先规定好的,在win下默认为2M,可生情空间比较小

堆:堆是向高地址扩展的数据结构,是不连续的内存区域,这是由于系统用链表来存贮空闲地址的,自然是不连续的,而链表的遍历方向由低地址向高地址,堆的大小受限于计算机系统中有效的虚拟内存,由此可见堆内存比较多大,而且比较灵活。


4、申请效率的比较

栈:系统分配,速度快,不收程序员控制

堆:有malloc/new 分配内存,速度相对较慢,易产生碎片(回收机制问题),不过勇气来比较方便


5、存储内容

 栈:在函数调用时,第一个进栈的是主函数中的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量,注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向开始的内存,也就是主函数中下一条指令,程序由该点继续运行

 堆:一般在头部用一个字节存放堆的大小,具体内容由程序员来定


6、内存回收

栈内存:系统自动回收

堆内存:free或delete显式回收,否则会造成内存泄露


使用栈就像去餐馆里吃饭,只管点菜(申请)、付钱吃饭(使用)、吃饱了就走人,不用收拾。很快捷方便但是自由度小

使用堆使用堆就像是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值