iOS内存分配 主要是堆和栈

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

栈区

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

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

在现代操作系统中,一个线程会分配一个栈. 当一个函数被调用,一个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内存分配 主要是堆和栈)