管理方式:栈由编译器自动管理;堆由程序员控制,使用方便,但易产生内存泄露。

生长方向:栈向低地址扩展(即”向下生长”),是连续的内存区域;堆向高地址扩展(即”向上生长”),是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。

空间大小:栈顶地址和栈的最大容量由系统预先规定(通常默认2M或10M);堆的大小则受限于计算机系统中有效的虚拟内存,32位Linux系统中堆内存可达2.9G空间。

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

分配方式:栈可静态分配或动态分配。静态分配由编译器完成,如局部变量的分配。动态分配由alloca函数在栈上申请空间,用完后自动释放。堆只能动态分配且手工释放。

分配效率:栈由计算机底层提供支持:分配专门的寄存器存放栈地址,压栈出栈由专门的指令执行,因此效率较高。堆由函数库提供,机制复杂,效率比栈低得多。Windows系统中VirtualAlloc可直接在进程地址空间中分配一块内存,快速且灵活。

分配后系统响应:只要栈剩余空间大于所申请空间,系统将为程序提供内存,否则报告异常提示栈溢出。

操作系统为堆维护一个记录空闲内存地址的链表。当系统收到程序的内存分配申请时,会遍历该链表寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点空间分配给程序。若无足够大小的空间(可能由于内存碎片太多),有可能调用系统功能去增加程序数据段的内存空间,以便有机会分到足够大小的内存,然后进行返回。,大多数系统会在该内存空间首地址处记录本次分配的内存大小,供后续的释放函数(如free/delete)正确释放本内存空间。

此外,由于找到的堆结点大小不一定正好等于申请的大小,系统会自动将多余的部分重新放入空闲链表中。

碎片问题:栈不会存在碎片问题,因为栈是先进后出的队列,内存块弹出栈之前,在其上面的后进的栈内容已弹出。而频繁申请释放操作会造成堆内存空间的不连续,从而造成大量碎片,使程序效率降低。

可见,堆容易造成内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和内核态切换,内存申请的代价更为昂贵。所以栈在程序中应用最广泛,函数调用也利用栈来完成,调用过程中的参数、返回地址、栈基指针和局部变量等都采用栈的方式存放。所以,建议尽量使用栈,仅在分配大量或大块内存空间时使用堆。

使用栈和堆时应避免越界发生,否则可能程序崩溃或破坏程序堆、栈结构,产生意想不到的后果。

转载于:https://www.cnblogs.com/wsw-seu/p/8276119.html

栈和堆的区别(转 知乎)相关推荐

  1. 栈和队列的区别,栈和堆的区别

    栈和队列的区别: 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的. 栈是先进后出,队列是先进先出. 栈只允许在表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除 ...

  2. 【ZZ】栈和堆的区别

    2019独角兽企业重金招聘Python工程师标准>>> 内存管理基本概念 C程序内存分配 1. 程序结构,下面列出C语言可执行程序的基本情况: [root@localhost Cte ...

  3. C语言里栈和堆的区别整理

    这里说的是C语言程序内存分配中的堆和栈.下面先谈谈C语言的内存管理: 可执行程序在存储时(没有调到内存)分为代码区(text).数据区(data)和未初始化数据区(bss)3个部分. (1)代码区(t ...

  4. 栈和队列的区别,栈和堆得区别

    栈和队列的区别: 1.栈是先进后出.队列是先进先出. 2.栈只允许在一端进行插入和删除,队列则在表的一段插入另一端删除. 3.在栈中遍历数据需要扫描全部数据,所以比较慢.而在队列中可以从两端进行所以速 ...

  5. 栈和堆的区别【总结】

    栈和堆的区别[总结] 1.1内存分配方面: 堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式是类似于链表.可能用到的关键字如下:new.m ...

  6. 栈和队列的区别与栈和堆的区别

    1.栈和队列的区别? 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的. 队列先进先出,栈先进后出. 栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删 ...

  7. C语言:栈和堆的区别

    c语言五大内存分区 栈区(stack):存放函数形参和局部变量(auto类型),由编译器自动分配和释放 堆区(heap):该区由程序员申请后使用,需要手动释放否则会造成内存泄漏.如果程序员没有手动释放 ...

  8. 内存、数据结构之栈和堆的区别?

    网上有一篇很好的文章,我差不多直接搬运过来了. 来源:http://www.cleey.com/blog/single/id/776.html 原文如下: 可能很多同学在这个概念上有些模糊,其实堆栈分 ...

  9. .net/c#中栈和堆的区别及代码在栈和堆中的执行流程详解之一(转)

    http://www.codingthink.com/c/20121223/201212231458171.html 原文出处: http://www.c-sharpcorner.com/Upload ...

最新文章

  1. ng-cordova和cordova区别
  2. 管理共享文件夹和使用FTP服务器
  3. Lunar New Year and Number Division
  4. 关于购买企业邮箱,谨防陷入几大误区
  5. 学习笔记(19):Python网络编程并发编程-互斥锁
  6. Rand函数使用和对补码的理解
  7. Linux Fedora8 下安装 IE6
  8. 二进制安装MySQL
  9. 《程序设计技术》第八章例程
  10. 2003系统如何搭建ftp服务器配置,WINDOWSSERVER2003系统架设FTP服务器配置方法.pdf
  11. 数独超难题目_号称世界上最难的一道数独题,你敢来挑战吗?据说答案只有一种...
  12. 超全面整理fastAPI(从入门到运用),进来看十秒钟再走不迟
  13. 服务器 虚拟机 崩溃,认识VMware虚拟机,系统崩溃或异常,可通过快照还原磁盘文件系统...
  14. Maya粒子-水滴表面流动效果
  15. ms project2010项目管理软件使用技巧总结
  16. Appium 测试APK
  17. 读查理·芒格---《穷查理宝典》
  18. html页面一个屏幕大小不一样,关于web页自动适配屏幕大小
  19. 品牌推广方法大全(收藏日后必有用处)
  20. 谈下微软企业生产力大学的Sharepoint Service 2010 的3天培训

热门文章

  1. Balanced Binary Tree leetcode java
  2. 《Effective Java》读书笔记--创建和销毁对象
  3. oracle监听器动态注册于静态注册的区别
  4. 十个利用矩阵乘法解决的经典题目
  5. Permission denied: make_sock: could not bind to address [::]:81 Apache 虚拟主机
  6. CV00-03-CV基本操作2
  7. else 策略模式去掉if_设计模式(三)——简单的状态模式代替if-else
  8. 交易所频频被盗,你该如何保护自己的数字资产?
  9. devops开发运维训练营_嗨,网络开发人员训练营的毕业生:这是您第一份工作需要了解的内容。...
  10. linux 565显示格式,RGB565转BMP格式 C语言程序