这周工作比较忙,加上之前从来没写过博客,所以不怎么会写,现在就先以文字写,后面通过学习写博客慢慢会改善成图文的形式,给我点时间,也许下一篇就是了,哈哈哈哈哈,谢谢大家了!
首先在上一次内容讲到的对象内存对齐补充一点,就是关于系统内存分配的优化。
对象的内存对齐是8字节,那么对于int,char一些字节不到8位的给他们分配8位,实在是浪费了,所以系统不会一味的进行字节对齐,不会4个字节或者1个字节就开辟8个内存空间,这样显然是一种浪费, 因此为了内存的优化,苹果做了优化重排,将int,char不到8字节的类型组合在了一起,避免了浪费内存情况。
如下图
接下来聊聊今天的主角,结构体对齐:
首先请注意:结构体的指针内存大小才是8,结构体大小是根据它内部属性的大小来进行开辟的
那么结构体内存对齐计算需要遵循一个原则,这个原则可以看我下面的表,也可以根据我简单易懂的分析:
我总结的:
第一,找出结构体中最大属性是谁 (比如double 是8个字节,最大属性是8字节)
第二,从0号位开始往下排,看当前位置的字节是不是该属性的整数倍,如果是,则可以从上一个属性位置后面开始放,如果不是,则不能放,得移到该属性的整数倍的位置放
第三,所有属性放完后,得出内部所需要的大小(假如为17)。那么当前结构体所需要的大小要为最大属性的整数倍,也就是8的整数倍,17不是8的整数倍,所以最终得出结构体的大小为24。
表格:
补充一张数据类型对应的字节数表格
那么,如果是结构体嵌套结构体呢:
很简单,看我这幅图, 从a,b,c,d排完之后接着排e这个结构体里面的内存大小,一直排到31位,那么31不是8的整数倍,所以最终得到的struct2结构体的内存大小是32
是不是简单通俗易懂,以后我的博客尽量做到化繁为简,同时也会加入一些带颜色的字体,看起来简单又明了。
最后扩展一下,说一下malloc内存开辟的计算算法
首先通过打印class_getInstanceSize 可以得知对象真正所需的内存大小,打印的结果是8字节对齐。其实对于一个对象来说,真正的内存对齐是8字节对齐,8字节对齐已经足够了
那么打印malloc_size 是系统开辟的内存大小,因为系统为了一切的容错, 所以开辟了16字节对齐的内存大小。
malloc_size的计算算法:
#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16
#define SHIFT_NANO_QUANTUM 4
公式: (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM
意思是先往右移4位,然后往左移4位,将末尾4位直接抹零, 得到的都是16的整数倍,这是另外一种16字节对齐的算法,这个算法在我看来更加简单
好了,今天就先说到这里了,明天周日,我还会写,周末我时间多一点,争取多写几篇,哈哈哈哈哈哈,加油!