iOS--------对堆、栈 存储空间的理解
Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release
栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就需要将其定义为成员变量。
1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。
2.堆区(heap):一般由程序员分配释放,若程序员不释放,则可能会引起内存泄漏。注堆和数据结构中的堆栈不一样,其类是与链表。
操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segment ”。
段“text segment ”是应用程序运行时应用程序代码存在的内存段。每一个指令,每一个单个函数、过程、方法和执行代码都存在这个内存段中直到应用程序退出。一般情况下,你不会真的不得不知道这个段的任何事情。
当应用开始以后,函数main() 被调用,一些空间分配在”stack” 中。这是为应用分配的另一个段的内存空间,这是为了函数变量存储需要而分配的 内存。每一次在应用中调用一个函数,“stack ”的一部分会被分配在”stack” 中,称之为”frame” 。新函数的本地变量分配在这里。
正如名称所示,“stack ”是后进先出(LIFO )结构。当函数调用其他的函数时,“stack frame ”会被创建;当其他函数退出后,这个“frame ”会自动被破坏。
“heap” 段也称为”data” 段,提供一个保存中介贯穿函数的执行过程,全局和静态变量保存在“heap”中,直到应用退出。
为了访问你创建在heap 中的数据,你最少要求有一个保存在stack 中的指针,因为你的CPU 通过stack 中的指针访问heap 中的数据。
你可以认为stack 中的一个指针仅仅是一个整型变量,保存了heap 中特定内存地址的数据。实际上,它有一点点复杂,但这是它的基本结构。
简而言之,操作系统使用stack 段中的指针值访问heap 段中的对象。如果stack 对象的指针没有了,则heap 中的对象就不能访问。这也是内存泄露的原因。
在iOS 操作系统的stack 段和heap 段中,你都可以创建数据对象。
stack 对象的优点主要有两点,一是创建速度快,二是管理简单,它有严格的生命周期。
stack 对象的缺点是它不灵活。创建时长度是多大就一直是多 大,创建时是哪个函数创建的,它的owner 就一直是它。不像heap 对象那样有多个owner ,其实多个owner 等同于引用计数。只有 heap 对象才是采用“引用计数”方法管理它。
stack 对象的创建
只要栈的剩余空间大于stack 对象申请创建的空间,操作系统就会为程序提供这段内存空间,否则将报异常提示栈溢出。
heap 对象的创建
操作系统对于内存heap 段是采用链表进行管理的。操作系统有一个记录空闲内存地址的链表,当收到程序的申请时,会遍历链表,寻找第一个空间大于所申请的heap 节点,然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。
例如:
NSString 的对象就是stack 中的对象,NSMutableString 的对象就是heap 中的对象。前者创建时分配的内存长度固定且不可修改;后者是分配内存长度是可变的,可有多个owner, 适用于计数管理内存管理模式。
两类对象的创建方法也不同,前者直接创建“NSString * str1=@"welcome"; “,而后者需要先分配再初始化“ NSMutableString * mstr1=[[NSMutableString alloc] initWithString:@"welcome"]; ”。
ios中堆栈的区别
管理方式:
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来讲,释放工作有程序员控制,容易产生memory Leak。
申请大小:
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶上的地址和栈的最大容量是系统预先规定好的,在Windows下,栈的大小是2M(也有的说1M,总之是编译器确定的一个常数),如果申请的空间超过了栈的剩余空间时候,就overflow。因此,能获得栈的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大笑受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
碎片的问题:
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存快从栈中弹出。
分配方式:
堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配是有alloc函数进行分配的,但是栈的动态分配和堆是不同的,他的动态分配由编译器进行释放,无需我们手工实现。
分配效率:
栈是机器系统提供的数据结构,计算机会在底层堆栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,他的机制是很复杂的。
iOS--------对堆、栈 存储空间的理解的更多相关文章
- Javascript的堆和栈的简单理解
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
- 堆”,"栈","堆栈","队列"以及它们的区别
如果你学过数据结构,就一定会遇到“堆”,"栈","堆栈","队列",而最关键的是这些到底是什么意思?最关键的是即使你去面试,这些都还会问到, ...
- iOS数据存储之属性列表理解
iOS数据存储之属性列表理解 数据存储简介 数据存储,即数据持久化,是指以何种方式保存应用程序的数据. 我的理解是,开发了一款应用之后,应用在内存中运行时会产生很多数据,这些数据在程序运行时和程序一起 ...
- java数据结构之(堆)栈
(堆)栈概述栈是一种特殊的线性表,是操作受限的线性表栈的定义和特点•定义:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈•特点:先进后出(FILO)或后进先出(L ...
- 堆,栈,内存管理, 拓展补充-Geekband
8, 堆,栈,内存管理 栈: local objects 在离开作用域之后就会被消除. 堆: new MyClass 一直会存在 静态对象: static local object 作用域在 ...
- iOS:堆(heap)和栈(stack)的理解
Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就 ...
- iOS中的堆(heap)和栈(stack)的理解
操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segme ...
- 堆&栈的理解(转)
(摘自:http://www.cnblogs.com/likwo/archive/2010/12/20/1911026.html) C++中堆和栈的理解 内存分配方面: 堆: 操作系统有一个记录空闲内 ...
- C#堆和栈的入门理解
声明:以下内容从网络整理,非原创,适当待入个人理解. 解释1.栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义:堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定 ...
随机推荐
- HDU 3592 World Exhibition (差分约束,spfa,水)
题意: 有n个人在排队,按照前后顺序编号为1~n,现在对其中某两人的距离进行约束,有上限和下限,表示dis[a,b]<=c或者dis[a,b]>=c,问第1个人与第n个人的距离最多可能为多 ...
- python爬虫之路——Python的re模块及其方法
介绍常用的三种方法:search(),sub(),findall() search():匹配并提取第一个符合规律的内容,然后返回一个正则表达式的对象 #提取字符串中的第一个数字 import re a ...
- BZOJ 4881: [Lydsy2017年5月月赛]线段游戏
4881: [Lydsy2017年5月月赛]线段游戏 Time Limit: 3 Sec Memory Limit: 256 MBSubmit: 164 Solved: 81[Submit][St ...
- python基础教程总结5——函数
1.函数创建 1).函数代码块以def关键词开头,后接函数标识符名称和圆括号()2).任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数3).函数的第一行语句可以选择性地使用文档字符串 ...
- JS中作用域和变量提升(hoisting)的深入理解
作用域(Scoping) javascript作用域之所以迷惑,是因为它程序语法本身长的像C家族的语言.我对作用域的理解是只会对某个范围产生作用,而不会对外产生影响的封闭空间.在这样的一些空间里,外部 ...
- CF Gym 100637K Microcircuits (DP)
题意:给你n个点,将这些点放在一个环上,问你不相交的连k条线的方案数.(没有重点) 题解:dp[i][j]表示i个点连j条线的方案数,那么新加一个点i, 情况1,i没有和之前的点相连,方案数为dp[i ...
- cv2.minAreaRect() 生成最小外接矩形
简介 使用python opencv返回点集cnt的最小外接矩形,所用函数为 cv2.minAreaRect(cnt) ,cnt是所要求最小外接矩形的点集数组或向量,这个点集不定个数. cv2 ...
- gzip, gunzip, zcat - 压缩或展开文件
总揽 gzip [ -acdfhlLnNrtvV19 ] [-S 后缀] [ 文件名 ... ] gunzip [ -acfhlLnNrtvV ] [-S 后缀] [ 文件名 ... ] zcat [ ...
- nginx之HTTP模块配置
listen 指令只能使用与server字段里 如果本地调用可以监听本地Unix套接字文件,性能更加,因为不用走内核网络协议栈 listen unix:/var/run/nginx.sock; ...
- 分类回归树(CART)
概要 本部分介绍 CART,是一种非常重要的机器学习算法. 基本原理 CART 全称为 Classification And Regression Trees,即分类回归树.顾名思义,该算法既 ...