底层探寻alloc都发生了什么

简介: 有关alloc之后, 底层代码的执行顺序以及解析

有关alloc之后, 底层代码的执行顺序以及解析


微信图片_20220509100122.jpg

alloc流程图


  1. 从上面的流程图可以很清晰的看到alloc之后的执行方法顺序
  2. 最重要的就是最后的三个方法 instanceSizecalloc 以及obj->initInstanceIsa


  • instanceSize: 先计算出要开辟多大内存空间
  • calloc: 开辟内存空间, 申请内存, 返回地址指针
  • obj->initInstanceIsa: 关联到相应的类


以下放上源码参考:


static ALWAYS_INLINE id  
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
                              int construct_flags = OBJECT_CONSTRUCT_NONE,
                              bool cxxConstruct = true,
                              size_t *outAllocatedSize = nil)  
{  
    ASSERT(cls->isRealized());  
    // Read class's info bits all at once for performance  
    bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();  
    bool hasCxxDtor = cls->hasCxxDtor();  
    bool fast = cls->canAllocNonpointer();  
    size_t size;  
    // 1:要开辟多少内存  
    size = cls->instanceSize(extraBytes);  
    if (outAllocatedSize) *outAllocatedSize = size;  
    id obj;  
    if (zone) {  
        obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);  
    } else {  
        // 2;怎么去申请内存  
        obj = (id)calloc(1, size);  
    }  
    if (slowpath(!obj)) {  
        if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {  
            return _objc_callBadAllocHandler(cls);  
        }  
        return nil;  
    }  
    // 3: ?
    if (!zone && fast) {  
        obj->initInstanceIsa(cls, hasCxxDtor);  
    } else {  
        // Use raw pointer isa on the assumption that they might be  
        // doing something weird with the zone or RR.  
        obj->initIsa(cls);  
    }  
    if (fastpath(!hasCxxCtor)) {  
        return obj;  
    }  
    construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;  
    return object_cxxConstructFromClass(obj, cls, construct_flags);  
}


  • 有关代码中的fastpathslowpath


//x很可能为真, fastpath 可以简称为 真值判断  
#define fastpath(x) (__builtin_expect(bool(x), 1))   
//x很可能为假,slowpath 可以简称为 假值判断  
#define slowpath(x) (__builtin_expect(bool(x), 0))


其中的__builtin_expect指令是由gcc引入的


  1. 目的:编译器可以对代码进行优化,以减少指令跳转带来的性能下降。即性能优化
  2. 作用:允许程序员将最有可能执行的分支告诉编译器。
  3. 指令的写法为:__builtin_expect(EXP, N)。表示 EXP==N的概率很大。
  4. fastpath定义中__builtin_expect((x),1)表示 x 的值为真的可能性更大;即 执行if 里面语句的机会更大
  5. slowpath定义中的__builtin_expect((x),0)表示 x 的值为假的可能性更大。即执行 else 里面语句的机会更大
  6. 在日常的开发中,也可以通过设置来优化编译器,达到性能优化的目的,设置的路径为:Build Setting --> Optimization Level --> Debug --> 将None 改为 fastest 或者 smallest


objc源码


访问参考

苹果开源源码汇总

更直接的地址


底层调试 (持续更新)


  1. 符号断点 (断点中增加 Symbolic Breakpoint, 然后增加要跟踪的函数名, 比如alloc, objc_alloc等内部函数名)
  2. 按住control + step into
  3. 汇编跟流程


微信图片_20220509100131.jpg

全局汇编断点



目录
相关文章
|
5月前
|
搜索推荐 编译器
【C初阶】进一步初识指针
【C初阶】进一步初识指针
|
6月前
|
编译器 C++
sizeof之谜与内存布局探秘
【7月更文挑战第18天】`sizeof`之谜与内存布局探秘: 在 C 和 C++ 中,`sizeof` 操作符用于确定类型或变量的字节数。基本类型如 `int` 的大小由编译器和平台决定。结构体因内存对齐可能使其实际大小大于成员总和,例如 `int` 可能按 4 字节对齐。数组的 `sizeof` 返回整个数组的内存空间。理解 `sizeof` 和内存布局有助于避免内存浪费和缓冲区溢出问题,确保程序高效可靠。
|
8月前
|
算法 数据库连接 程序员
深度剖析:C++内存池的设计与实现
深度剖析:C++内存池的设计与实现
507 0
|
存储 算法
学C的第二十六天【指针的进阶(二)】
6 . 函数指针数组 (1). 含义: 函数指针数组 是一个数组,是用于存放 函数指针 的数组。 例如:
深度剖析指针(下)——“C”
深度剖析指针(下)——“C”
|
存储 C语言 C++
深度剖析指针(上)——“C”
深度剖析指针(上)——“C”
|
存储 缓存 Java
【Java难点攻克】「NIO和内存映射性能提升系列」彻底透析NIO底层的内存映射机制原理与Direct Memory的关系
【Java难点攻克】「NIO和内存映射性能提升系列」彻底透析NIO底层的内存映射机制原理与Direct Memory的关系
274 0
【Java难点攻克】「NIO和内存映射性能提升系列」彻底透析NIO底层的内存映射机制原理与Direct Memory的关系
|
设计模式 前端开发 算法
OC底层知识(七) : 架构设计
OC底层知识(七) : 架构设计
169 0
OC底层知识(七) : 架构设计
|
安全 算法 Java
深度揭秘垃圾回收底层,这次让你彻底弄懂她(中)
深度揭秘垃圾回收底层,这次让你彻底弄懂她(中)
深度揭秘垃圾回收底层,这次让你彻底弄懂她(中)

热门文章

最新文章