美文网首页
iOS内存分配 主要是堆和栈

iOS内存分配 主要是堆和栈

作者: 佟掌柜666 | 来源:发表于2018-04-25 16:13 被阅读0次

    整理下最近看的文章,主要取自这里

    栈区

    由编译器自动分配释放,存放函数的参数值,局部变量等值。

    栈是一个用来存储局部和临时变量的存储空间。

    在现代操作系统中,一个线程会分配一个栈. 当一个函数被调用,一个stack frame(栈帧)就会被压到stack里。里面包含这个函数涉及的参数,局部变量,返回地址等相关信息。当函数返回后,这个栈帧就会被销毁。而这一切都是自动的,由系统帮我们进行分配与销毁。对于程序员来说,我们无须自己调度。

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

    堆区

    一般由程序员分配释放,若程序员不释放,则可能会引起内存泄漏。

    堆从本质上来说,程序中所有的一切都在内存中(有些东西是不在堆栈中的,但在这篇文章中我们不作讨论)。在堆上,我们可以任何时候分配内存空间以及释放销毁它。你必须显示的请求在堆上分配内存空间,如果你不使用垃圾回收机制,你必须显示的去释放它。这就是在你的函数调用前需要完成的事情。简单来说,就是malloc与free。

    通常以这种方式创建对象:

    NSObject *obj = [[NSObject alloc] init];

    系统会在栈上存储obj这个指针变量,它所指的对象在堆中。通过[NSObject alloc]系统会为其在堆中开辟一块内存空间,并为其生成NSObject所需内存结构布局。

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

    栈对象:

         优点:1.高速,在栈上分配内存是非常快的。

                    2.简单,栈对象有自己的生命周期,你永远不可能发生内存泄露。因为他总是在超出他的作用域时被自动销毁了

         缺点:栈对象严格的定义了生命周期也是其主要的缺点,栈对象的生命周期不适于Objective-C的引用计数内存管理方法。

    在objective-c中只支持一个类型对象:blocks。

    关于在block中的对象的生命周期问题。出现这问题的原因是,block是新的对象,当你使用block时候,如果你想对其保持引用,你需要对其进行copy操作,(从栈上copy到堆中,并返回一个指向他的指针),而不是对其进行retain操作

    堆对象:

        优点:可以自己控制对象的生命周期。

        缺点:需要程序员手动释放,容易造成内存泄漏。

    全局区(静态区)

    全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后有系统释放。

    注意:全局区又可分为:

    未初始化全局区:.bss段

    初始化全局区:data段。

    举例:int a;未初始化的。int a = 10;已初始化的。

    例子代码:

    int a = 10;  全局初始化区

    char *p;  全局未初始化区

    main{

    int b; 栈区

    char s[] ="abc"栈

    char *p1; 栈

    char *p2 ="123456";123456\\\\0在常量区,p2在栈上。

    static int c =0; 全局(静态)初始化区

    w1 = (char *)malloc(10);

    w2 = (char *)malloc(20);

    分配得来得10和20字节的区域就在堆区。

    }

    常量区

    存放常量字符串,程序结束后由系统释放

    代码区

    存放函数的二进制代码

    相关文章

      网友评论

          本文标题:iOS内存分配 主要是堆和栈

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