iOS 底层探索alloc的原理01

本文详细探讨了Objective-C中alloc方法的工作原理,通过分析objc4源码,揭示了alloc调用的内部流程,包括_objc_rootAlloc、calloc等方法。同时,解释了对象内存对齐规则以及实例大小计算,展示了苹果如何在内存效率和性能之间取得平衡。通过对内存分配的深入理解,有助于提升iOS应用的性能优化能力。
摘要由CSDN通过智能技术生成

运行场景,新建一个项目工程(我命名为zzz) ,创建一个新的类JSPerson,然后在view controller里面执行 代码:JSPerson * p = [JSPerson alloc]; 打上断点。
在这里插入图片描述新建一个项目工程(我命名为zzz)
在这里插入图片描述创建一个新的类JSPerson

在苹果的开源网站(https://opensource.apple.com/tarballs/)去download对应的源码。这边我们看的是alloc 所以找objc4-838.

在源码的main方法写上代码用来观察,alloc方法究竟做了什么。

结果我们发现-进入alloc以后的方法循序为

  1. alloc
  2. _objc_rootAlloc
  3. calloc
  4. alloc
  5. calloc
  6. _objc_rootAllocWithZone
    然后返回对象
    那么为什么会经历两次的call alloc 呢?

接下来我们回到开始的zzz并且在viewcontroller上写上代码
在这里插入图片描述

在这里插入图片描述进入deBug汇编模式,
然后发现
alloc - objc_alloc - objc_messageSend-alloc-_objec-rootAlloc – _objc_rootAllocWithZone –
所以可以确定alloc 通过_objc_rootAllocWithZone方法生成对象并返回
而第一次alloc 执行了一遍fixupMessageRef

instanceSize 探索

alloc方法在objc-runtime-new.mm 文件中 _class_createInstanceFromZone方法创建并分配内存空间。
其中InstanceSize为计算创建的这个实例对象分配多大的内存空间

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;

    size = cls->instanceSize(extraBytes);
    if (outAllocatedSize) *outAllocatedSize = size;

    id obj;
    if (zone) {
        obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
    } else {
        obj = (id)calloc(1, size);
    }
    if (slowpath(!obj)) {
        if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
            return _objc_callBadAllocHandler(cls);
        }
        return nil;
    }

    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);
}
    inline size_t instanceSize(size_t extraBytes) const {
        if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
            return cache.fastInstanceSize(extraBytes);
        }

        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }
    /*其中extraBytes为额外字节,alignedInstanceSize为字节对齐的方法--计算对象需要内存大小8字节对齐
    caloc 系统分配的内存---16字节对齐
    if (size < 16) size = 16;说明类最小的字节为16字节*/

结构体内存对齐的规则(苹果结构体内存的计算方式)

1:数据成员对齐规则:结构(struct)的第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储)。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储)。

3:收尾工作:结构体的总大小,也就是sizeof的结果必须是其内部最大成员的整数倍,不足的要补齐。

struct person1{
    int age ; //4 [0-3]
    short leg; //2 [4-5]
    char name; //1 [6]
    long hight; // 8 [7,8-15]
    short hand; //2 [16-17]
    long finger;//8 [18,19,20,21,22,23,24-31] ==> 32
}person1;

struct person2{
    int age ; // 4 [0-3]
    long hight; // 8 [4,5,6,7,8-15]
    short hand; // 2 [16-17];
    long finger; // 8 [24-31] ==>32
    struct person1 teammate; //32 ====64
}person2;

为什么苹果计算内存使用8字节而,系统分配内存使用16字节计算呢,16字节分配这就是苹果的空间换时间的最优算法,分配空间太小那么计算量增加,如果空间分配多了又会造成分配内存过多即资源过度浪费。16字节就是资源分配最优的解。

对象本质就是objc——object – isa(类的指针) + 成员变量的值

在终端输入; clang -rewrite-objc main.m 编译一下.m文件会输出一个main.cpp 文件
然后我们打开可以看到所有类都是 objc-object 的结构体,对象= isa指针 加上成员变量的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值