1. 栈(Stack): 
        位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。
2. 堆(Heap): 
       由new申请的内存,由delete负责释放。
3. 自由存储区(Free Storage): 
  由程序员用malloc()/calloc()/realloc()(C语言的库函数,C语言没有类的概念,没有new运算符,new ≈ malloc()+构造函数)分配空间,由free()释放。如果程序员忘记free()了,则会造成内存泄漏,程序结束时可能会有操作系统回收,也许就一直占用着直至关机。

4. 全局区/静态区(Global Static Area): 
         全局变量和静态变量存放区,程序一经编译好,该区域便存在。在C++中,由于编译器会给全局变量和静态变量自动初始化赋值,所以没有区分初始化和未初始化变量。由于全局变量一直占据内存空间且不易维护,推荐少用。程序结束时释放。
5. 常量存储区:

这是一块比较特殊的存储区,专门存储不能修改的常量(如果采用非正常手段更改,当然也是可以的)。

堆与栈的区别:

管理方式:
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员delete(),容易产生memory leak。

空间大小:
一般来讲在 32 位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改:打开工程,依次操作菜单如下:Project->Setting->Link,在 Category 中选中 Output,然后在 Reserve 中设定堆栈的最大值和 commit。注意:reserve 最小值为 4Byte;commit 是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。

碎片问题:
对于堆来讲,频繁的 new/delete 势必会造成内存空间的物理不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列。

生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。

分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由 malloc 函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是 C/C++ 函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

从这里我们可以看到,堆和栈相比,由于大量 new/delete 的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP 和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。

最新文章

  1. PHP跳转页面的几种实现方法详解
  2. 17.5---珠玑妙算,四个槽,红色黄色绿色蓝色(CC150)
  3. 如何使用Iveely的数据存储引擎 Iveely Database
  4. Django自定义模型(model)中的字段标签
  5. shell内部变量
  6. excel筛选两列值是否相同,如果相同返回第三列值
  7. (转)Java字符串应用之密码加密与验证
  8. 二十三种设计模式及其python实现
  9. php禁用一些重要功能
  10. Newly Setting up a CentOS-7 system
  11. python数据类型(一)
  12. xml文件的规则
  13. TCP发送源码学习(3)--tcp_transmit_skb
  14. [Linux] LVS虚拟服务器四层负载均衡
  15. js 库
  16. DataUtils对Connection的获取、释放和关闭的操作学习
  17. 自定义的圆形ProgressBar
  18. Javascript 浮点计算问题分析与解决
  19. Newtonsoft.Json 序列化器的重写
  20. 转转转--Java File和byte数据之间的转换

热门文章

  1. ViewPager实现引导页
  2. Java控制图片按比例缩放- (注意内存释放)
  3. 国内git项目托管平台
  4. c++调用lua
  5. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'dd' in 'where clause'
  6. 逻辑回归 Logistic Regression
  7. AndroidStudio开发环境配置-Windows
  8. Web应用请求和响应 HTTP相关
  9. UV动画
  10. ASP.NET是否存在客户端控件?