iOS--------对堆、栈 存储空间的理解

Objective-C对象在内存中是以的方式分配空间的,而且堆内存是由你释放的,即releaseios

由编译器管理自动释放的,在方法中(函数体)定义的变量一般是栈内所以若是你的变量要跨函数的话就须要将其定义为成员变量。程序员

1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量等值。其操做方式相似于数据结构中的栈。objective-c

2.堆区(heap):通常由程序员分配释放,若程序员不释放,则可能会引发内存泄漏。注堆和数据结构中的堆栈不同,其类是与链表。算法

操做系统iOS 中应用程使用的计算机内存不是统一分配空间运行代码使用的空间在三个不一样的内存区域,分红三个段:“text segment “,“stack segment ”,“heap segment ”。数据结构

 

“text segment ”是应用程序运行时应用程序代码存在的内存段每个指令,每个单个函数、过程、方法和执行代码都存在这个内存段中直到应用程序退出。通常状况下,你不会真的不得不知道这个段的任何事情。函数

当应用开始之后,函数main() 被调用,一些空间分配在”stack” 中。这是为应用分配的另外一个段的内存空间,这是为了函数变量存储须要而分配的 内存。每一次在应用中调用一个函数,“stack ”的一部分会被分配在”stack” 中,称之为”frame” 。新函数的本地变量分配在这里。spa

正如名称所示,“stack ”是后进先出(LIFO )结构。当函数调用其余的函数时,“stack frame ”会被建立;当其余函数退出后,这个“frame ”会自动被破坏。操作系统

“heap” 段也称为”data” 段,提供一个保存中介贯穿函数的执行过程,全局和静态变量保存在“heap”中,直到应用退出.net

为了访问你建立在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++函数库提供的,他的机制是很复杂的。

相关文章
相关标签/搜索