美文网首页
了解内存对齐原理

了解内存对齐原理

作者: _涼城 | 来源:发表于2020-09-12 17:06 被阅读0次
    对象的内存空间
    首先创建一个Person
    @interface Person : NSObject
    
    @property (nonatomic, copy) NSString *name;
    @property (nonatomic, copy) NSString *nickName;
    
    @property (nonatomic, assign) int age;
    @property (nonatomic, assign) long height;
    
    @property (nonatomic) char c1;
    @property (nonatomic) char c2;
    @end
    
    实例化一个Person对象
    Person *person = [Person alloc];
    person.name      = @"Cc";
    person.nickName  = @"cc";
    person.age       = 18;
    person.c1        = 'a';
    person.c2        = 'b';
    
    调试对象地址的信息
    16字节输出信息.png

    我们可以正常输出字符串对象属性的信息,但是无法找出基本数据类型信息。

    调试基本数据类型信息
    输出基本数据类型信息.png

    这是因为苹果通过属性重排使得完成了内存优化,这种内存对齐方式来源于结构体内存对齐。

    结构体内存对齐
    结构体对象的内存

    首先创建两个结构体对象Struct1

    struct Struct1 {
        double a;   
        char   b;   
        int    c;     
        short  d;   
    }struct1;
    

    Struct2

    struct Struct2 {
        double a;  
        int    b;      
        char   c;     
        short  d;   
    }struct2;
    

    通过SizeOf函数获取Struct1Struct2的大小分别是2416,那么为什么占用的内存大小不相等呢?

    在探索结构体内存之前,我们需要先了解内存对齐的原则。

    内存对齐的原则
    1. 数据成员对⻬规则

      结构体或联合体的数据成员,第⼀个数据成员放在offset为0的地⽅以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩的整数倍开始。

      例如,int为4字节,则要从4的整数倍地址开始存储

    2. 结构体作为成员

      如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储。

      例如,struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从8的整数倍开始存储

    3. 结构体的总⼤⼩

      结构体的大小必须是其内部最大成员的整数倍,不足的要补齐。

    计算结构体内存的大小

    根据数据类型对应的内存大小以及内存对齐的原则,计算Struct1Struct2的大小。

    • 计算Struct1的大小

      1. 变量double a,字节大小8,范围(0,7)
      2. 变量char b,字节大小1,8为1的整数倍,则b的位置为8
      3. 变量int c,字节大小为4,12是4的整数倍,则c的内存范围为(12,15)
      4. 变量short d,字节大小为2,16是2的整数倍,则d的内存范围为(16,17)

      最终结构体的大小为最大成员double a的整数倍24

    • 继续计算Struct2的大小

      1. 变量double a,字节大小8,范围(0,7)
      2. 变量int b,字节大小4,8为4的整数倍,则b的内存范围为(8,11)
      3. 变量char c,字节大小为1,12是1的整数倍,则c的内存范围为(12)
      4. 变量short d,字节大小为2,14是2的整数倍,则d的内存范围为(14,15)

      最终结构体的大小为最大成员double a的整数倍16

    属性重排

    根据上述可以得出一个结论,结构体内存大小与结构体成员内存大小的顺序有关,苹果中将类中的属性进行重排,来达到优化内存的目的。

    获取内存大小的三种方式

    sizeof,获取该数据类型占用空间的大小。

    class_getInstanceSize,获取实例对象中成员变量的内存大小,是采用8字节对齐,参照的对象的属性内存大小。

    malloc_size,获取系统实际分配的内存大小,采用16字节对齐,参照的整个对象的内存大小,对象实际分配的内存大小必须是16的整数倍。

    相关文章

      网友评论

          本文标题:了解内存对齐原理

          本文链接:https://www.haomeiwen.com/subject/cwiwektx.html