iOS开发资料收集区iOS

iOS-底层原理6:malloc 源码分析

2020-09-25  本文已影响0人  AcmenL

iOS-底层原理2:alloc、init、new探析中,有介绍过alloc的三个核心方法,其中一个就是calloc,即申请内存,这一节,我们深入探究calloc如何开辟空间。

alloc核心方法

objc4中分析calloc 源码

打开objc4源码,跟着alloc流程 + alloc --> objc_rootAlloc --> callAlloc --> _objc_rootAllocWithZone --> _class_createInstanceFromZone进入到_class_createInstanceFromZone方法。

_class_createInstanceFromZone方法

点击calloc进入内部,只能看到calloc声明,无法进一步进行探索,怎么办?

下载libmalloc源码下载最新版,继续探索。

libmalloc中分析calloc源码

step1:打开libmalloc项目,新建一个Target

step2:在main中使用calloc创建一个指针

#import <Foundation/Foundation.h>
#import <malloc/malloc.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        void *p = calloc(1, 24);
        NSLog(@"%p", p);
    }
    return 0;
}

step3:进入calloc源码

calloc实现

上述的default_zone是一个默认的空间大小,目的就是引导程序进入一个创建真正zone的流程; size是我们传入的空间的大小。

step4:进入malloc_zone_calloc

malloc_zone_calloc实现

step5:进入zone->calloc,发现command+鼠标并不能跳转到对应的实现

怎么办?

step6:在zone->calloc代码处打上断点,等程序执行到断点时,有两种方式可以查看zone->calloc源码实现;

1、按住control + step into,进入calloc的源码实现

2、在控制台输入lldb命令p zone->callocde查找源码实现

通过控制台查找zone->callocde源码

step7:全局搜索default_zone_calloc方法,找到具体实现

default_zone_calloc实现

step8:进入runtime_default_zone源码

runtime_default_zone实现

step9:进入inline_malloc_default_zone源码

inline_malloc_default_zone实现

查看malloc_zones的值发现是·NULL·,可以得出,此时的zone还未赋值

step10:回到default_zone_calloc源码,在zone->calloc处打上断点,继续执行,用在step6介绍的方式选其一

step11:全局搜索nano_calloc方法,进入源码

nano_calloc实现

step12:进入_nano_malloc_check_clear源码

_nano_malloc_check_clear实现

step13:进入segregated_size_to_fit源码

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) {
               // NANO_REGIME_QUANTA_SIZE = 16
        size = NANO_REGIME_QUANTA_SIZE; // Historical behavior
    }
        // SHIFT_NANO_QUANTUM = 4,  (size+15) >> 4  (+15 右移4位)
    k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM; // round up and shift for number of quant  
        // << 4 (左移4位)
    slot_bytes = k << SHIFT_NANO_QUANTUM;                           // multiply by power of two quanta size
    *pKey = k - 1;                                                  // Zero-based!

    return slot_bytes;
}

#define SHIFT_NANO_QUANTUM      4
#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM)   // 16

iOS-底层原理5:内存对齐
中已经讲解过

step14:回到_nano_malloc_check_clear方法,进入segregated_next_block源码,这个方法主要就是获取内存指针

step15:第一次走segregated_next_block方法,band不存在,缓存也不存在,所以会调用segregated_band_grow开辟新的band

segregated_next_block实现

暂时到此,后续再补充

上一篇下一篇

猜你喜欢

热点阅读