内存五大区
严格意义来说,这不能算是Objective-C的特性,应该是属于C语言的特性,这并不是本文的重点,重点是每个区块职责是什么。
哪五大区
- 栈区(stack):由编译器自动分配并释放,存放函数的参数值,局部变量等。栈是系统数据结构,对应线程/进程是唯一的。栈是向低地址扩展的数据结构,是一块连续的内存的区域;先进后出(FILO—First-In/Last-Out)
- 优点:快速高效
- 缺点:内存大小有限制(iOS主线程栈大小1MB,其他线程是512KB。(Mac也只有8M)),数据不灵活
- 堆区(heap):由程序员分配和释放,如果程序员不释放,程序结束后,可能由操作系统回收,类似于链表;堆是向高地址扩展的数据结构,是不连续的内存区域;先进先出(FIFO—first in first out)
- 优点:灵活方便,数据适应面广泛
- 缺点:需手动管理、速度慢、容易产生内存碎片
- 全局区(静态区):全局变量和静态变量的存储区,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后有系统释放。
- 常量区:存放常量字符串,程序结束后由系统释放
- 代码区:存放函数的二进制代码
虚拟内存区域分配图
举个栗子
int main { NSInteger i = 233; NSString *string = @"string"; NSObject *obj = [[NSObject alloc] init]; NSLog(@"i->%p-----string->%p---&string->%p",&i, string,&string); NSLog(@"obj->%p-----&obj->%p",obj,&obj); }
考虑下,上面3个局部变量在内存中是如何分布的?
ok,我们来打印下指针
i->0x7ffee2cd4a48-----string->0x10cf2a0a8---&string->0x7ffee2cd4a40 obj->0x6000011d93e0-----&obj->0x7ffee2cd4a38
- i毋庸置疑,肯定是在栈上,看到&i地址是在0x7段
- 我们打印了string的对象地址与string对象的指针地址,分别在0x1段与0x7段,说明string的值”string”是在常量区;而string这个对象的指针是在栈区
- 我们又打印了obj的对象地址与obj对象的指针地址,分类在0x6段与0x7段。至于obj对象的指针地址同上所述,肯定是在栈区了;而obj的对象是在0x6段,因为是alloc方式分配的,所以就是在堆区的