Runtime-OC对象的内存

作者: cyh老崔 | 来源:发表于2019-05-03 16:22 被阅读6次

    一. NSObject对象分配内存大小

    有两个方法可以得到一个指针对象的大小:

    • class_getInstanceSize(Class _Nullable cls): 得到编译器计算的大小, 即实际使用的大小
    • size_t malloc_size(const void *ptr): 得到实际分配的堆内存大小
    #import <objc/runtime.h>
    #include <malloc/malloc.h>
    
            NSObject *obj= [NSObject new];
            size_t size1 = class_getInstanceSize([NSObject class]);
            size_t size2 = malloc_size((__bridge void *)obj);
            NSLog(@"size1 = %zd, size2 = %zd", size1, size2);
    

    输出:

    size1 = 8, size2 = 16
    

    可看到实际分配的堆内存大小>实际使用的内存大小
    ref: https://forums.developer.apple.com/thread/114963

    问题: oc为什么这样设计呢? 猜测:

    • 备用空间
    • 为什么是2倍? 正如方法缓存, 扩充时都是扩充一倍

    二. 类对象组成

    1. 定义一个简单的类:
    @interface Boy : NSObject
    {
        @public
        int _weight;
    }
    @end
    
    @implementation Boy
    @end
    
    1. clang下:
    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
    

    为什么指定生成cpp文件呢? 因为oc底层即cpp, 以免生成文件过大

    生成文件中, 相关代码如下:

    struct Boy_IMPL {
        
        struct NSObject_IMPL NSObject_IVARS;
        int _weight;
    };
    
     struct NSObject_IMPL {
     Class isa;
     };
    

    即类BoyBoy_IMPL 结构体, 而Boy_IMPL 结构体中包含下面两个成员变量:

    Class isa; //每个对象都有的隐藏成员变量
    int _weight; //其它定义的成员变量
    

    2.1 体现在NSObject与Boy对象的内存大小如下:

    size_t objSize = class_getInstanceSize(NSObject.class);
    size_t boySize = class_getInstanceSize(boy.class);
    NSLog(@"objSize: %zd, boySize: %zd", objSize, boySize);
    

    输出:

    objSize: 8, boySize: 16
    

    可看到:

    • 一个空的NSObject对象, 就有8个字节, 即isa指针的大小
    • Boy对象的内存大小为16, 因为内存对齐, 所以Boy对象大小为8的倍数

    2.2 体现在内存实际内容:

    • 查看内存地址:


      Boy对象地址
    • 地址对应内存:


      内存地址
    • arm是大端架构, 低位在高地址. 只查看自己的内存: 前16字节即可.

    • 前8个字节是isa指针

    • 后4个字节是0x42, 即66, 我们给_weight赋的值

    • 最后4个字节是内存对齐空余出来的4个字节, 并已经初始化为0

    2.3 LLDB读取内存也可以看到这16字节的值

    内存值

    相关文章

      网友评论

        本文标题:Runtime-OC对象的内存

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