系统层知识OC 底层

iOS底层原理之内存对齐原理

2019-12-23  本文已影响0人  尘舒

内存对齐的规则

32位下采用4字节对齐,64位下采用8字节对齐

struct A {
    int a; //4字节,0-3
    char b;//1字节,4 补齐567
    double c;// 8字节 8-15
    int *p;  // 8字节 16-23    大小24字节
}AA;

struct B {
    int a; //0,1,2,3 补齐4,5,6,7
    int *p; // 8,9,10,11,12,13,14,15
    char b; // 16补齐17,18,19,20,21,22,23
    double c;// 24,25,26,27,28,29,30,21,32
}BB;

struct C {
    int a; // 0-3,
    char b;// 4,补齐5-7
    double c;// 8-15
    int *p;// 16-23
    struct B bb; //结构体最大成员为8,从24开始,24+32 = 56字节是8的整数倍ok
}CC;
// 输出
NSLog(@"A = %d - B = %d - C = %d",sizeof(AA), sizeof(BB), sizeof(CC));
A = 24 , B = 32, C = 56

对象的内存对齐

 size_t size = cls->instanceSize(extraBytes);
// 64位下 WORD_MASK为7,也就是8字节对齐
static inline uint32_t word_align(uint32_t x) {
    // (x + 7) >> 3 << 3
    return (x + WORD_MASK) & ~WORD_MASK;
}
static inline size_t word_align(size_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}
    uint32_t alignedInstanceSize() {
        return word_align(unalignedInstanceSize());
    }

    size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }
void *
calloc(size_t num_items, size_t size)
{
    void *retval;
    retval = malloc_zone_calloc(default_zone, num_items, size);
    if (retval == NULL) {
        errno = ENOMEM;
    }
    return retval;
}
ptr = zone->calloc(zone, num_items, size);
(lldb) p zone->calloc
(void *(*)(_malloc_zone_t *, size_t, size_t)) $1 = 0x0000000100381a4b (.dylib`default_zone_calloc at malloc.c:249)
(lldb) 
(lldb) p zone->calloc
(void *(*)(_malloc_zone_t *, size_t, size_t)) $2 = 0x000000010038302e (.dylib`nano_calloc at nano_malloc.c:878)
(lldb) 
static void *
nano_calloc(nanozone_t *nanozone, size_t num_items, size_t size)
{
    size_t total_bytes;

    if (calloc_get_size(num_items, size, 0, &total_bytes)) {
        return NULL;
    }

    if (total_bytes <= NANO_MAX_SIZE) {
                // 核心代码,返回一个分配好的地址
        void *p = _nano_malloc_check_clear(nanozone, total_bytes, 1);
        if (p) {
            return p;
        } else {
            /* FALLTHROUGH to helper zone */
        }
    }
    malloc_zone_t *zone = (malloc_zone_t *)(nanozone->helper_zone);
    return zone->calloc(zone, 1, total_bytes);
}
#define SHIFT_NANO_QUANTUM      4
#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM)

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
    }
        //  这里的关键代码进行16字节对齐
        // (size + 1<<4 -1) >> 4
    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;
}

小结

上一篇 下一篇

猜你喜欢

热点阅读