美文网首页杏仁丶的iOS学习专题iOS开发牛叉的demo
iOS开发积累知识(一)----理解堆栈

iOS开发积累知识(一)----理解堆栈

作者: NBeanN | 来源:发表于2017-05-27 16:09 被阅读56次
    1

    0.堆和栈都是内存;

    1.堆是由程序员手动释放的,不释放的话会导致内存泄露;

    栈是由编译器管理自动释放的,申请过大内存由于空间不足以分配导致内存溢出;

    2.堆创建的时候会向程序申请,程序收到申请的时候,遍历链表,寻找第一个大于所申请的堆节点,然后将该节点从空间节点链表中删除,并把该节点空间分配给程序。堆有多个owner,其实多个owner等同于引用计数。只有堆才是采用“引用计数”方法管理它;

    栈创建速度快,管理简单,有严格的生命周期,先进后出,但缺点是它不灵活。创建时长度是多大就一直是多大,创建时是哪个函数创建的,它的owner就一直是它。

    3.堆是向高地址扩展的数据结构,是不连续的内存区域,是因为系统使用链表来存储空闲内存地址的,自然是不连续的,而链表的遍历是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。所以堆的空间比较灵活,也比较大。

    栈的大小一般是2M或是1M,是一块连续的内存区域,如果申请的空间超过了栈的剩余空间,就会overflow;

    4.为什么堆是不连续的,因为对于堆来讲,频繁的new/delete会造成内存空间的不连续,从而导致大量的碎片,使程序效率降低。

    但是对于栈来说,则不会出现,因为栈是先进后出的队列,他们是如此的一一对应,以至于用于都不可能从一个内存块从栈中弹出。

    5.堆的释放是程序员控制的,容易产生memory Leak。

    栈是由编译器自动管理,不需要手动控制。

    6.堆都是动态分配的,没有静态分配的堆。

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

    7.堆的分配是由c/c++函数库提供的,它的机制是很复杂的。

    栈是机器系统提供的数据结构,计算机会在底层堆栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就使得栈的效率比较高。

    8.堆:

    是由alloc分配的内存,速度比较慢,而且容易产生内存碎片,不过用起来最方便

    栈:

    由系统自动分配,速度较快,不会产生内存碎片堆

    9.使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

    使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

    10.例如:

    NSString 的对象就是stack 中的对象,NSMutableString 的对象就是heap 中的对象。前者创建时分配的内存长度固定且不可修改;后者是分配内存长度是可变的,可有多个owner, 适用于计数管理内存管理模式。

    两类对象的创建方法也不同,前者直接创建“NSString * str1=@"welcome"; “,而后者需要先分配再初始化“ NSMutableString * mstr1=[[NSMutableString alloc] initWithString:@"welcome"]; ”

    堆和栈的关联和区别:

    1.堆是OC对象在内存中分配的形式,由人创建由人realease;

    栈是OC对象在内存中分配的形式,由编译器管理自动realease;

    NSString 的对象就是stack 中的对象,NSMutableString 的对象就是heap 中的对象。前者创建时分配的内存长度固定且不可修改;后者是分配内存长度是可变的,可有多个owner, 适用于计数管理内存管理模式。

    2.为了访问你创建在heap 中的数据,你最少要求有一个保存在stack 中的指针,因为你的CPU 通过stack 中的指针访问heap 中的数据。

    3.stack 对象的优点主要有两点,一是创建速度快,二是管理简单,它有严格的生命周期。stack 对象的缺点是它不灵活。创建时长度是多大就一直是多 大,创建时是哪个函数创建的,它的owner 就一直是它。不像heap 对象那样有多个owner ,其实多个owner 等同于引用计数。只有 heap 对象才是采用“引用计数”方法管理它。

    管理方式:

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

    申请大小:

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

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

    碎片的问题:

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

    分配方式:

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

    分配效率:

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

    参考文章1 

    参考文章2

    菜鸟走向大牛,大家共同前进,如果觉得不错,请给个赞/关注。

    一起交流学习,有问题随时欢迎联系,邮箱:383708669@qq.com

    相关文章

      网友评论

        本文标题:iOS开发积累知识(一)----理解堆栈

        本文链接:https://www.haomeiwen.com/subject/pnuqfxtx.html