美文网首页底层开发-基础知识
iOS - 获取内存大小的三种方式

iOS - 获取内存大小的三种方式

作者: malgee | 来源:发表于2020-09-10 22:27 被阅读0次

    获取内存大小的三种方式分别是:

    • sizeof

    • class_getInstanceSize

    • malloc_size


    1. sizeof

    是一个运算符,并不是一个函数。

    sizeof 传进来的是类型,用来计算这个类型占多大内存,这个在 编译器编译阶段 就会确定大小并直接转化成 8 、16 、24 这样的常数,而不是在运行时计算。参数可以是数组、指针、类型、对象、结构体、函数等。

    NSLog(@"%zd  %zd   %zd", sizeof(double), sizeof(int), sizeof(void(*)));
    
    // 输出  8    4    8
    

    不难发现,double 占 8字节, int 4 字节,void(*) 代表指针占8字节

    它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。

    由于在编译时确定占用内存大小,因此sizeof不能用来返回动态分配的内存空间的大小。

    2. class_getInstanceSize

    用于获取类的实例对象占用的内存大小,并返回具体的字节数,其本质就是获取实例对象中成员变量的内存大小
    依赖于<objc/runtime.h>,返回创建一个实例对象所需内存大小

    NSObject *objc = [[NSObject alloc] init];
            
    NSLog(@"sizeof:  %zd", sizeof(objc));
            
    NSLog(@"class_getInstanceSize:  %zd", class_getInstanceSize([objc class]));
    
    打印输出结果: 
    sizeof:  8
    class_getInstanceSize:  8
    

    我们可以通过查看iOS开源的objc4源码了解 class_getInstanceSize() 具体是怎么计算的

      1. 搜索 class_getInstanceSize 函数
    size_t class_getInstanceSize(Class cls)
    {
        if (!cls) return 0;
        return cls->alignedInstanceSize();
    }
    
      1. 调用了 alignedInstanceSize 函数
        uint32_t unalignedInstanceSize() const {
            ASSERT(isRealized());
            return data()->ro()->instanceSize;
        }
    
      // 返回一个类的ivar(成员变量)所占空间的大小
        uint32_t alignedInstanceSize() const {
            return word_align(unalignedInstanceSize());
        }
    
      1. 计算占用内存大小 (采用8字节对齐)
    #  define WORD_MASK 7UL   
    
    // 计算占用内存大小算法 (8字节对齐)
    static inline uint32_t word_align(uint32_t x) {
      //           (8 + 7) & ~ 7
        return (x + WORD_MASK) & ~WORD_MASK;
    }
    

    计算出的占用内存大小是8

    image.png

    3. malloc_size

    计算对象实际分配的内存大小,这个是由系统完成的(采用16字节对齐),
    依赖于<malloc/malloc.h>,返回系统实际分配的内存大小

    malloc源码分析中的segregated_size_to_fit

    #define SHIFT_NANO_QUANTUM      4
    #define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM)   // 16
    
    static MALLOC_INLINE size_t
    segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey)
    {
        size_t k, slot_bytes;
    
        if (0 == size) {
            size = NANO_REGIME_QUANTA_SIZE; // Historical behavior
        }
        k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM; // round up and shift for number of quanta
        slot_bytes = k << SHIFT_NANO_QUANTUM;                           // multiply by power of two quanta size
        *pKey = k - 1;                                                  // Zero-based!
    
        return slot_bytes;
    }
    

    算法原理:先右移4位 k = (size + 15) >> 4 , 然后结果左移4位 k << 4 ,其中 右移4位 左移4位相当于将后4位抹零,跟 k/16 * 16一样 ,是16字节对齐算法,小于16就成0了

    image.png

    相关文章

      网友评论

        本文标题:iOS - 获取内存大小的三种方式

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