app启动之后,在内存中的布局情况,基本如下:
代码段
编译之后代码存放的地方,比如方法的实现就存放在这里
数据段
- 字符串常量
- 已初始化的数据:已初始化的全局变量、静态变量等
- 未初始化的数据:未初始化的全局变量、静态变量等
栈
- 由编译器自动分配释放,存放函数的参数值,局部变量等值。
- 栈是向低地址扩展的数据结构
- 是一块连续的内存的区域
堆
- 通过alloc、malloc、calloc等动态分配的空间
- 堆是向高地址扩展的数据结构
- 是不连续的内存区域
代码验证
// 已初始化的全局变量
int initedGlobalVar = 10;
// 未初始化的全局变量
int uninitedGlobalVar;
// 函数
void test() {
NSLog(@"test");
}
- (void)viewDidLoad {
[super viewDidLoad];
// 已初始化的静态变量
static int initedStaticVar = 20;
// 未初始化的静态变量
static int uninitedStaticVar;
// 已初始化的局部变量
int initedScopeVar = 20;
// 未初始化的局部变量
int uninitedScopeVar;
// 字符串常量,分配在数据段,内存地址最低
NSString *constStr = @"abc";
// 堆区,通过alloc、malloc、calloc分配的空间
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSObject *obj3 = [[NSObject alloc] init];
NSLog(@"\n代码段-test=%p\n数据段-constStr=%p\n数据段-&initedGlobalVar=%p\n数据段-&initedStaticVar=%p\n数据段-&uninitedGlobalVar=%p\n数据段-&uninitedStaticVar=%p\n堆-obj1=%p\n堆-obj2=%p\n堆-obj3=%p\n栈-&initedScopeVar=%p\n栈-&uninitedScopeVar=%p", test,
constStr, &initedGlobalVar, &initedStaticVar, &uninitedGlobalVar, &uninitedStaticVar, obj1, obj2, obj3, &initedScopeVar, &uninitedScopeVar);
}
打印结果
代码段-test = 0x10a4bf290
数据段-constStr = 0x10a4c10a0
数据段-&initedGlobalVar = 0x10a4c1f70
数据段-&initedStaticVar = 0x10a4c1f74
数据段-&uninitedGlobalVar = 0x10a4c203c
数据段-&uninitedStaticVar = 0x10a4c2038
堆-obj1 = 0x6000005842f0
堆-obj2 = 0x600000584300
堆-obj3 = 0x600000584310
栈-&initedScopeVar = 0x7ffee573d8ac
栈-&uninitedScopeVar = 0x7ffee573d8a8
从打印结果我们可以看出:
- 从代码段到栈空间,内存地址是从低向高扩展的
- 在栈空间,内存地址是从高向低扩展的
- 在堆空间,内存地址是从低向高扩展的