一、iOS 程序的内存布局
从低到高
- 保留
- 代码段(__Text)
- 数据段(__ Data)
- 字符串常量
- 已初始化数据
- 未初始化数据
- 堆(heap):比栈的内存地址小,比数据段的内存地址大
- 内存分配:从低到高分配
- 栈(stack):内存地址比较大
- 内存分配:从高到底分配
- 内核区
一般只使用 代码段、数据段、堆、栈
二、代码段
- 定义: 编译之后的代码
- 当打开一个项目后,看到的 AppDelegate.m ViewController.m 这些 在编译之后,都会变成 机器码(010101), 这些代码最终都要进入到内存区域。
- 当进入到内存区域,他们就被放在了 代码段
三、数据段:
1、定义:
- 字符串常量:比如 NSString *str = @“123”
- 内存地址比较小
- 已初始化数据: 已初始化的全局变量、静态变量等
- 内存地址比 字符串常量 要大一些
- 未初始化数据:未初始化的全剧变量、静态变量等
- 内存地址比 已初始化数据 要大一些
为什么一个比一个的内存地址大?
- 内存地址比 已初始化数据 要大一些
- 这是因为 越到高处,地址越大。
2、 解答:字符串常量
-
NSString *str1 = @“123”;
-
NSString *str2 = @“123”;
-
str1 和 str2 指向的都是同一个对象 @“123”
-
这是因为系统会直接将 @“123” 放到常量区域
我们可以打印一下:NSLog(@"%p,%p",str1,str2);
- 结果是:0x10671e068、0x10671e068
3、 已初始化数据
- 全局变量:
- 静态变量
4、未初始化数据
- 全局变量
- 在 大括号外面 写
int c ;
- 在 大括号外面 写
- 静态变量
- 在带括号 里面 写
static int d;
- 在带括号 里面 写
四、栈
1、 定义:函数调用开销
2、解释:一般来说,函数里面的局部变量是放在 栈 里面的
例如:定义两个变量
- (void)main {
int e;
int f = 10;
}
这个时候的变量不管有没有初始化,都直接放到 栈内存空间中。
栈的内存空间分配是由高到底 。也就是说分配的内存空间地址越来越小。
上面的例子里面的 e 和 f 。
* 变量e 的内存地址比较 大 ,变量f 的内存地址比较小
五、堆
1、定义:通过 alloc、malloc、calloc 等动态分配的空间
2、分配的内存空间地址越来越大。
六、内存地址
打印结果:
字符串常量应该是 内存地址最低的。我们来看一下
我们可以把打印结果排序下:
- 由低到高 :
- 字符串常量:str = 0x10ecd2068
- 已初始化数据
- 全局变量: a = 0x10ecd2db8
- 静态变量: c = 0x10ecd2dbc
- 未初始化数据
- 全局变量: b = 0x10ecd2e84
- 静态变量: d = 0x10ecd2e80
- 堆
- alloc动态分配 : obj = 0x60800000d5e0
- 栈
- 未初始化数据: e = 0x7ffee0f2efe4
- 已初始化数据: f = 0x7ffee0f2efe0
- 解释:
- 可以看到 a 和 c 的地址 ,他们相差了 4个字节,这是因为是 Int 类型
- 系统给的栈空间和堆空间 的地址是非常大的
- 栈空间和堆空间 的地址非常的相近