您的位置:首页 > 其它

剖析程序中的栈与堆的内存分配

2015-03-17 21:37 218 查看
在计算机系统中,运行的应用程序的数据都保存在内存中,不同类型的数据所保存在的区域不同,应用程序中总共有五个内存区域:
(1)、栈区【stack】:由编译器自动分配并释放,一般存放函数的参数值,局部变量等
(2)、堆区【heap】:由程序员分配和释放内存,如果程序员不释放,程序结束时,可能会由操作系统回收
(3)、全局区【静态区】【static】:全局变量和静态变量的存储是放在一起的,而该区又分为两种情况,一种是已初始化的,另一种是未初始化的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放
(4)、文字常量区:存放常量字符串,程序结束后由系统释放
(5)、程序代码区:存放函数的二进制代码
其中全局区,常量区和代码区会随着应用程序启动被加载进内存,当应用程序被销毁后才会被释放,所以我们应该将重点放在栈区和堆区上

一、内存的申请方式
栈:由系统自动分配
堆:需要程序员自己使用alloc,new等操作申请

二、申请后系统的响应
栈:在栈的剩余空间大于所申请空间的前提下才会为系统分配内存,否则将报异常提示栈溢出
堆:堆内存的分配会经过三步,遍历链表、为程序寻找并分配第一块大于申请大小的空间、将分配出去有剩余的空间回收。
(1)、操作系统中有一个记录空闲内存的链表,当系统接收到程序的申请时会遍历该链表;
(2)系统会寻找链表中第一个空间大于所申请空间的堆节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序
(3)、由于找到的堆节点的大小不一定正好等于申请的大小,所以系统会自动的将剩余的那部分重新放入空闲链表中。

三、申请大小的限制
栈:栈内存的分配是由高地址向低地址扩展的数据结构,是一块连续的内存区域,栈顶的地址和栈的最大容量是系统预先规定好的,也就是说每一次分配的内存大小是由系统确定的。
堆:堆内存的分配是由低地址向高地址扩展的数据结构,是不连续的内存区域,这是由于系统使用链表来存储空闲内存地址,自然是不连续的,而链表是由低地址向高地地址遍历的,堆的大小受限于计算机系统中有效的虚拟内存。由此可见堆获得的空间比较灵活,也比较大。

四、申请效率
栈:由系统分配,速度快
堆:是由alloc分配内存,速度比较慢且容易产生内存碎片,不过用起来最方便

五、存储内容
栈:变量名(不带*)相当于是指向栈区数据的指针别名
堆:要访问堆中得数据,必须通过指针的方式才可以进行,指针的类型聚丁了访问堆中数据的方式
(1)、操作系统以匿名的方式记录已经分配的内存区域,也就是只记录内存地址和大小,不记录具体类型;
(2)、当某一内存区域不再使用时,程序需要通知操作系统回收该内存区域,从而可以保证该内存区域被其他程序再次使用,否则该区域将永远无法被再次分配,这就是内存泄露;
(3)、如果某一区域已经被释放但仍然试图访问该区域,就会提示“bad access”,也就是“坏的访问”,也可以称之为“野指针访问”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: