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、代码区
存放函数体的二进制代码
注:
- 在iOS中,堆区的内存是应用程序共享的堆中的内存分配是系统负责的,系统使用一个链表来维护已经分配的内存空间(系统仅记录,不做管理)
- app启动后,代码区、常量区、全局区大小已经固定。因此指向这些区的指针不会产生崩溃的错误。但堆区和栈区是一直变化的--堆的创建和销毁、栈的出栈和入栈。这里容易产生崩溃比如野指针报错(内存已释放)
其他相关
- 初始化方法以 new, alloc, retain,copy 开头都是在堆区,也包括被引用计数管理的对象。常量这些就会在栈区。
除去 NSString *aString = @"aaa"这种编译时会转换为常量,其它的 Objective-C 对象,理论上来说,都是在堆区. - block是个例外,block 分堆block、栈block、全局block
- 一般情况下可以通过打印出地址判断他是在堆还是栈内存中,栈是高地址往下,堆是低地址往上,一般看到0x7fff....这种的肯定是是在栈中的,要注意一点的是TEXT段,像NSString这种基本放在TEXT段中,这种地址比堆地址更低,也很好区分