底层开发-基础知识

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

2020-09-10  本文已影响0人  malgee

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


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() 具体是怎么计算的

size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    return cls->alignedInstanceSize();
}
    uint32_t unalignedInstanceSize() const {
        ASSERT(isRealized());
        return data()->ro()->instanceSize;
    }

  // 返回一个类的ivar(成员变量)所占空间的大小
    uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
    }
#  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
上一篇 下一篇

猜你喜欢

热点阅读