iOS - 内存对齐分析

2020-10-23  本文已影响0人  Gumball_a45f

iOS 内存对其原则

  1. 数据成员对⻬规则结构(struct)(或联合(union))的数据成员,第⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存储。

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

  3. 收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍,不⾜的要补⻬

看这些文字比较难理解接下来例子解析,先了解一下基本数据类型所需要的内存

基本数据类型所占用的内存大小
设置一个结构体
struct Mystruct{
    char a;     //1字节
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
}Mystruct1;

NSLog(@"%lu-%lu",sizeof(Mystruct1);

根据以上规则来计算结构体的大小,设min(m,n)m为起始位置,n为所需内存

还有一种情况就是结构体中嵌套结构体1,则把结构体1内部最大成员大小看作结构体大小,如:

//1、结构体嵌套结构体
struct Mystruct2{
    double a;   //8字节
    struct Mystruct b  //内部最大double b 8字节; 
}Mystruct2;
NSLog(@"%lu-%lu",sizeof(Mystruct1),sizeof(Mystruct2));

获取内存大小的三种方式

  1. sizeof 计算类型占用的内存大小,可计算基本数据类型,对象,指针

    • 计算基本数据类型占用的内存,每个类型所占用的内存大小不同
    • 计算对象类型、指针,该类所占内存大小为8,可以计算验证sizeof([NSObject alloc] init])
  2. class_getInstanceSize 计算对象实际占用内存大小,该内存大小是依据对象的属性来计算的,如果对象没有属性则占用的内存为8,该方法用到8字节对齐word_align()

  3. malloc_size 计算对象实际分配的内存大小,这个计算是由系统完成的,实际分配的内存和实际占用内存不一定相等,该方法用到16字节对齐

内存优化

对象中有相同的属性,但顺序不同的话他们所占的内存会相同吗?

struct Mystruct1{
    char a;     //1字节
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
}Mystruct1;

struct Mystruct2{
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
    char a;     //1字节
}Mystruct2;
image.png 很显然,属性的排列顺序不同会导致对象所占的内存大小 不同。

通过测试可以知道,若是结构体中的成员是根据内存从大到小的顺序定义, 那么根据内存对齐规则来计算结构体内存大小时只需要补齐少量的内存填充即可满足内存对齐规则,这就是苹果采用的利用空间换时间

总结

所以,这里可以总结下苹果中的内存对齐思想:

上一篇下一篇

猜你喜欢

热点阅读