一、内存对齐原理
先给出一段代码,并打印对象的存储空间内容


由 0x0000001200006261 可以引出内存优化---内存拼接和内存对齐。
内存对齐原则(借鉴大神的理论):
1:数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第 一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要 从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组, 结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存 储。
2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从 其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b 里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大 成员的整数倍.不足的要补⻬。
给出一段代码说明

二、对象申请内存 VS 系统开辟内存
获取内存空间大小的两个API:
class_getInstanceSize:传入一个类对象返回一个对象的实例至少申请的内存,等价于sizeof;对象里面的属性空间8字节对齐
malloc_size:返回系统实际分配的内存大小;系统开辟的空间16字节对齐

根据上图提出两个问题:
1)当类里没有任何属性的情况下,为什么class_getInstanceSize 获取的内存大小要比 malloc_size 获取到的大8?
先给出class_getInstanceSize的调用流程及最终源码 class_getInstanceSize -> alignedInstanceSize -> word_align


此图可看出对象里的属性为 8 字节对齐。
再看 alloc 计算 size 源码


2)为什么当类里有属性并且大于属性内存大于16字节的时候,class_getInstanceSize 获取的内存是8字节对齐,malloc_size 获取到内存是16字节对齐?
因为 alloc 创建对象并申请内存的时候的流程(关于alloc调用流程,OC 对象原理(1)有提到)会到达, _class_createInstanceFromZone 这个方法(下图)

三、calloc 原理探索
1)先下载并配置 malloc 源码
2)追踪流程计算size并返回的地方
calloc调用流程:calloc -> malloc_zone_calloc -> default_zone_calloc -> nano_calloc -> _nano_malloc_check_clear -> segregated_size_to_fit
segregated_size_to_fit 返回了 slot_bytes,可以推断这就是确定计算size大小的算法了



现在就回答上面的第二个问题:因为前面的8字节对齐的参照物是对象里面的属性,而属性的类型最大也是8字节,所以属性内存大小8字节对齐并不会有什么问题。但是系统分配的内存大小为16字节对齐,是因为此时参考的因素是整个对象,要是8字节对齐就很大内存溢出的风险。