堆空间、栈空间和堆栈平衡_adousen的博客-程序员宅基地

技术标签: output  算法  WIN32/MFC工程  存储  windows  

堆(heap)与栈(stack)是程序存储空间上的一组概念。

应用程序启动时

程序启动时,windows的PE装载器会将PE文件(可执行文件,Unix/Linux 上是ELF)的不同部分的内容装入不同的内存区域。

程序的数据段包括.data段(全局变量)和.rdata段(静态变量和常量)。而PE装载器只能从程序中读出已初始化的全局变量和静态变量,并将它们放在的一段专门的初始化的数据的内存区域上。而未初始化的全局变量和静态变量则存放在一段专门的非初始化数据段的内存区域上开辟空间,并且都被初始化为0。这二者合在一起被称为data area。

程序的正文段(可再入程序,即可被多个进程共享的一串指令,是只读的)则是被装载器装入到被称为code area内存区域。

程序中任何需要动态分配内存的变量(如使用malloc/free或new/delete)的内存分配是在堆进行。而局部变量与自动变量的内存分配是在栈进行。

堆、栈

堆空间的内存分配属于用户级的内存分配,所分配的内存需要手动释放,否则会造成内存泄漏。当然,在应用程序销毁时,也能得到释放。在32位的系统中堆得大小可达4G,可见堆得空间可以很大。但是堆的频繁分配与释放可能会带来内存碎片,也可能会造成内核模式和用户模式(Unix/Linux 的内核态和用户态)频繁切换和申请内存,带来性能上的损失。例如可能会为了分配一块内存,C/C++库函数会按照一定的算法在堆内存中搜索,看是否有可用的足够大小的空间。如果没有足够大小的空间(可能是由于内存碎片太多),就有可能通过执行系统调用去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后再返回。但是,我们要看到堆为我们提供了足够的对内存使用的灵活性。特别是在某些时候,动态地分配内存能为我们大大的节约内存空间。

栈空间的内存分配则由系统负责管理的,是系统级的内存分配,一般不需要我们手动的控制。局部变量、以及被调用的子程序的返回地址以及寄存器信息都存放在栈中。我们知道栈是FIFO(先进先出)的结构,因而栈空间上的内存始终是连续占用的,不会出现内存碎片。然而,栈的大小是有限制的。

例如,在VC6下面,默认的栈空间大小是1M。当然,可以修改:

  打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit

堆与栈

堆与栈是两个不同的概念,但是我们习惯上却经常说“堆栈”这个词,这造成了许多的误会。因此,我们还要了解堆与栈的联系与区别

我们用一张图来直观的说明堆、栈在内存上的位置关系。

内存图示

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/adousen/article/details/4193825

智能推荐

四、Unity4.6UI--------------Button_dreamsnow127的博客-程序员宅基地

Interactable: 是否接受响应事件Transition:鼠标过渡效果Navigation:鼠标响应顺序?Visualize:?On Click() 指定响应鼠标事件函数Color Tint:按钮使用颜色渐变Color Multiplier:?Fade Duration:渐变时间Sprite Swap:使用图片切换。

JS小数位保留两位小数--toFixed()_guchuanlong的博客-程序员宅基地

parseInt,parseFloat,parseDouble在JS中是将值转换成相应的类型;你必须要这样,才能实现:         alert(parseFloat(12.44644).toFixed(2)); 想要精确到几位,就tofixed几 在JS中格式化数据保留两位小数的函数的多种方法最好方法:  var   a   =   9.39393;

UNIX环境高级编程学习之路(一)----文件I/O_drlmemory的博客-程序员宅基地

对于UNIX环境编程,工作中经常会用到相关知识,作为学习UNIX环境编程的经典书籍--UNIX环境高级编程,是每个UNIX编程人员必看的经典书籍之一,为了将相关知识重新进行学习,以系统的整合所学知识,遂以博文形式作为总结。一、概述    Unix系统可用的文件I/O函数--打开文件,读文件,写文件等,大多数文件I/O只需用到5个函数:open、read、write、ls

大数据 IMF传奇 如何搭建 8台设备的SPARK分布式 集群_段智华的博客-程序员宅基地_imf大数据

1.下载spark-1.6.0-bin-hadoop2.6.tgz2.解压[email protected]:/usr/local/setup_tools# tar -zxvf spark-1.6.0-bin-hadoop2.6.tgz3.配置Spark的全局环境变量输入# vi /etc/profile打开profile文件,按i可以进入文本输入模式,在profile文件的增

虚函数、纯虚函数、override_那年聪聪的博客-程序员宅基地_函数override

虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。 ——摘自MSDN描述:override保留字表示当前函数重写了基类的虚函数。目的:1.在函数比较多的情况下可以提示读者某个函数重写了基类虚函数(表示这个虚函数是从基类继承,不是派生类自己定义的);2.强制编译器检查某个函数是否重写基类虚函数,如果没有则报错。虚函数:关键字“virtual”,在基类中声明,且在基类中有函数体;纯...

随便推点

navicat15 for linux 桌面快捷方式创建_taodanc的博客-程序员宅基地

在桌面上创建navicat.desktop[Desktop Entry]Type=ApplicationName=Navicat Premium 15GenericName=Database Development Tool# 图标位置Icon=/opt/navicat15/.DirIcon# navicat15-premium-cs.AppImage位置Exec=/opt/navicat15/navicat15-premium-cs.AppImage Categories=Develop

Yii CDBCriteria常用方法_SherlockGh的博客-程序员宅基地_cdbcriteria

Yii CDbCriteria 常用方法 注:$c = new CDbCriteria();是ActiveRecord的一种写法,使ActiveRecord更加灵活,而不是手册中DAO(PDO)和Query Builder。小小点评一下:感觉这部分手册做的一般。 链接地址:http://www.yiiframework.com/doc/api/1.1/CDbCriter

Caused by: java.sql.SQLException: 违反协议 error code [17401]_duanlianvip的博客-程序员宅基地

今天在Java编程遇到了一个奇怪的现象,jar包应用往Oracle11g插入数据时效率很低,经查应用日志,有的可以插入成功,有的报错:###Cause:java.sql.SQLException:违反协议;uncategorizedSQLExceptionforSQL[];SQLstate[null];errorcode[17401];违反协议;nested...

UE使用教程_攻城狮的博客-程序员宅基地_ue括号匹配

UE 正则表达式Tip 1: 如何去掉所编辑文本中包含特定字符串的行?         这则技巧是在UltraEdit的帮助文件里提到.CTRL+R 调出来替换(Replace)窗口,选中"使用正则表达式";然后用查找 %*你的字符串*^p 替换成空内容即可.如,我当前有个文本文件,需要去掉所有包含 http://www.dbanotes.net/ 这个字符串的行,查找 %*http://

Linux 不杀进程的情况下,如何释放磁盘资源_weixin_30595035的博客-程序员宅基地

最近项目组人员反馈一个问题:即磁盘空间满了,但是并没看到有什么文件占用空间:[[email protected] home]# df -hFilesystem Size Used Avail Use% Mounted on/dev/xvda2 40G 6.4G 31G 18% /tmpfs 7.8G ...

JDK 1.8 新特性_会飞地太阳的博客-程序员宅基地_jdk18的新特性

jdk1.8(Java 8)是java语言开发的一个主要版本,Oracle公司于2014年3月18日发布Java 8.它支持函数式编程,新的JavaScript引擎等等。1. Lambda表达式 它允许把函数作为一个方法的参数 格式:(parameters参数)-> expression表达体或方法体 parameters参数: ...

推荐文章

热门文章

相关标签