博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS 堆和栈的在内存中管理方式
阅读量:2345 次
发布时间:2019-05-10

本文共 1304 字,大约阅读时间需要 4 分钟。

C语言内存分配

Objective-C从名字来看就可以知道是一门超C语言,所以了解C语言的内存模型对于理解Objective-C的内存管理有很大的帮助。C语言内存模型图如下:

这里写图片描述

从图中可以看出内存被分成了5个区,每个区存储的内容如下:

1.栈区(stack):存放函数的参数值、局部变量的值等,由编译器自动分配释放,通常在函数执行结束后就释放了,其操作方式类似数据结构中的栈。栈内存分配运算内置于处理器的指令集,效率很高,但是分配的内存容量有限,比如iOS中栈区的大小是2M。

2.堆区(heap):就是通过new、malloc、realloc分配的内存块,它们的释放编译器不去管,由我们的应用程序去释放。如果应用程序没有释放掉,操作系统会自动回收。分配方式类似于链表。
3.静态区:全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后,由系统释放。
4.常量区:常量存储在这里,不允许修改的。
5.代码区:存放函数体的二进制代码。

管理方式:

对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来讲,释放工作有程序员控制,容易产生memory Leak。

申请大小:

栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶上的地址和栈的最大容量是系统预先规定好的,在Windows下,栈的大小是2M(也有的说1M,总之是编译器确定的一个常数),如果申请的空间超过了栈的剩余空间时候,就overflow。因此,能获得栈的空间较小。

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

碎片的问题:

对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存快从栈中弹出。

分配方式:

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

分配效率:

栈是机器系统提供的数据结构,计算机会在底层堆栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,他的机制是很复杂的。

栈区和堆区的区别主要为以下几点:

对于栈来说,内存管理由编译器自动分配释放;对于堆来说,释放工作由程序员控制。

栈的空间大小比堆小许多。
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持,所以分配效率比堆高。
栈中存储的变量出了作用域就无效了,而堆由于是由程序员进行控制释放的,变量的生命周期可以延长。

参考文章

你可能感兴趣的文章
PHP页面纯静态化与伪静态化
查看>>
分享网页到微信朋友圈,显示缩略图的方法
查看>>
PHP参数类型限制
查看>>
IOS博客项目搭建-12-刷新数据-显示最新的微博数提示
查看>>
Laravel5 Markdown 编辑器使用教程
查看>>
php文件上传与下载
查看>>
Python3学习教程
查看>>
Python3学习笔记01-第一个Python程序
查看>>
Laravel5学生成绩管理系统-01-安装-建表-填充数据
查看>>
Mac OSX下使用apt-get命令
查看>>
Mac下安装PHP的mcrypt扩展的方法(自己总结的)
查看>>
关于html_entity_decode、空格 以及乱码
查看>>
Box2d no gravity
查看>>
mario collision
查看>>
tiled 地图工具
查看>>
小游戏
查看>>
旋转关节绳子
查看>>
射箭box2d
查看>>
cocos2d iphone-wax cocowax
查看>>
angribird level editor
查看>>