iOS程序的内存布局

Posted by AndyCao on September 15, 2019

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

从打印结果我们可以看出:

  • 从代码段到栈空间,内存地址是从低向高扩展的
  • 在栈空间,内存地址是从高向低扩展的
  • 在堆空间,内存地址是从低向高扩展的