iOS 内存分区-- 栈、堆、全局区、常量区、代码区

1,427 阅读2分钟

5大区

1、栈区(Stack)

会存一些局部变量,函数跳转跳转时现场保护(寄存器值保存于恢复),这些系统都会帮我们自动实现,无需我们干预。 所以大量的局部变量,深递归,函数循环调用都可能耗尽栈内存而造成程序崩溃 高地址向低地址扩展的数据结构,是一块连续的内存区域

由编译器自动分配释放

eg:函数中定义:int a

2、堆区(Heap)

比如alloc申请内存,free释放内存。我们创建的对象也都放在这里。低地址向高地址扩展的数据结构。不连续。

由程序员分配和释放

eg:函数中定义: [NSMutableArray arrayWithCapacity:1];//分配而来的8字节的区域就在堆中(相当于alloc分配内存)

3、全局区/静态区

全局变量和静态变量的存储是放在一块的。 初始化的全局变量和初始化的静态变量在一块区域,未初始化的全局变量和未初始化静态变量在相邻的另一块区域

程序结束后由系统释放

eg:static NSString str2 = @"string"

4、常量区

常量字符串存在该区,只读

程序结束由系统释放

eg: @"123"

5、代码区

存放函数体的二进制代码

注:

  1. 在iOS中,堆区的内存是应用程序共享的堆中的内存分配是系统负责的,系统使用一个链表来维护已经分配的内存空间(系统仅记录,不做管理)
  2. app启动后,代码区、常量区、全局区大小已经固定。因此指向这些区的指针不会产生崩溃的错误。但堆区和栈区是一直变化的--堆的创建和销毁、栈的出栈和入栈。这里容易产生崩溃比如野指针报错(内存已释放)

其他相关

  • 初始化方法以 new, alloc, retain,copy 开头都是在堆区,也包括被引用计数管理的对象。常量这些就会在栈区。 除去 NSString *aString = @"aaa"这种编译时会转换为常量,其它的 Objective-C 对象,理论上来说,都是在堆区.
  • block是个例外,block 分堆block、栈block、全局block
  • 一般情况下可以通过打印出地址判断他是在堆还是栈内存中,栈是高地址往下,堆是低地址往上,一般看到0x7fff....这种的肯定是是在栈中的,要注意一点的是TEXT段,像NSString这种基本放在TEXT段中,这种地址比堆地址更低,也很好区分