美文网首页
iOS程序的内存布局

iOS程序的内存布局

作者: iOS丶lant | 来源:发表于2022-01-11 14:50 被阅读0次

    iOS程序安装之后,是以Mach-o文件的格式保存在iOS设备里面,当启动程序时,对应的Mach-o文件就会被加载进内存。那么iOS程序的内存布局是什么样子的呢?

    先上图:

    image

    代码区

    • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
    • 程序运行时的代码会被编译成二进制,存进内存的代码区域。

    全局/静态区

    • 该区是编译时分配的内存空间,在iOS中一般以0x1开头,程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
    • 未初始化的全局变量和静态变量,在BSS区,即未初始化区,.bss。
    • 已初始化的全局变量和静态变量,在数据区,即初始化区,.data。

    常量区

    • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
    • 存放常量:整型、字符型、浮点、字符串等。

    堆区

    • 是不连续的内存从低地址向高地址存储,遵循先进先出(FIFO)原则。
    • 堆的地址空间iOSx86架构下以0X6开头,空间的分配是动态的。
    • 需要关注变量的生命周期,不及时释放会造成内存泄露。
    • OC中使用alloc、new开辟空间创建的对象内存放在堆区(而指向内存的指针还是在栈里)。
    • C语言中使用malloc、calloc、realloc分配的空间,需要free释放。

    栈区

    • 是一段连续的内存区域,从高地址向低地址存储,遵循先进后出(FILO)原则。
    • 在x86架构下,栈的地址一般为0X7开头。
    • 一般在运行时进行分配,内存空间由系统管理,变量过了作用域范围后内存便会自动释放。
    • 参数、函数、局部变量都放在栈区。
    • 参数入栈是从前往后入栈。而结构体入栈是从后往前入栈。

    栈区与堆区对比

    • 栈是一段连续的内存区域,堆是不连续的内存
    • 栈系统自动回收内存,堆需要开发人员手动释放
    • 栈内存大小有限制,内存空间小,堆内存空间大

    代码验证

    int a = 1;                   //已初始化全局变量
    int b;                       //未初始化全局变量
    
    int main(int argc, char * argv[]) {
        NSString * appDelegateClassName;
        @autoreleasepool {
            // Setup code that might create autoreleased objects goes here.
            appDelegateClassName = NSStringFromClass([AppDelegate class]);
    
            static int c = 2;    //已初始化静态变量
    
            static int d;         //未初始化静态变量
    
            int e;                //未初始化局部变量
    
            int f = 2;           //已初始化局部变量
    
            NSString *str = @"字符串常量";//字符串常量
    
            NSObject *obj = [[NSObject alloc] init];//通过alloc动态分配(实例对象)
    
            NSLog(@"\n&a=%p\n&b=%p\n&c=%p\n&d=%p\n&e=%p\n&f=%p\nstr=%p\nobj=%p\n",
                          &a, &b, &c, &d, &e, &f, str, obj);
        }
        return UIApplicationMain(argc, argv, nil, appDelegateClassName);
    }
    
    

    输出结果

    &a=0x1052fd528
    &b=0x1052fd534
    &c=0x1052fd52c
    &d=0x1052fd530
    &e=0x7ffeea9061e4
    &f=0x7ffeea9061e0
    str=0x1052fc168
    obj=0x6000019a8020
    
    
    • 通过输出结果可以看到,a、b、c、d在全局/静态区,地址也确实已0x1开头;
    • str=0x1052fc168 在常量区;
    • e、f 是局部变量,在栈;
    • obj=0x6000019a8020在堆;

    这样就验证了开始的结论!!

    相关文章

      网友评论

          本文标题:iOS程序的内存布局

          本文链接:https://www.haomeiwen.com/subject/uaibcrtx.html