美文网首页
iOS - 内存对齐分析

iOS - 内存对齐分析

作者: Gumball_a45f | 来源:发表于2020-10-23 14:28 被阅读0次

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为所需内存

  • 变量a:占1个字节,从0开始,此时min(0,1),即 0 存储a
  • 变量b:占8个字节,从1开始,此时min(1,8),1不能整除8,继续往后移动,知道min(8,8),从8开始,即8-15 存储 b
  • 变量c:占4个字节,从16开始,此时min(16,4),16可以整除4,即 16-19存储c
  • 变量d:占2个字节,从20开始,此时min(20, 2),20可以整除2,即20-21存储d
  • 收尾工作:通过计算Mystruct需要内存为21字节,但Mystruct中最大成员需要8个字节,所以Mystruct所需内存必须为8的整数倍24不足则补齐。

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

//1、结构体嵌套结构体
struct Mystruct2{
    double a;   //8字节
    struct Mystruct b  //内部最大double b 8字节; 
}Mystruct2;
NSLog(@"%lu-%lu",sizeof(Mystruct1),sizeof(Mystruct2));
  • 变量a:占8个字节,从0开始,此时min(0,8),即 0-7 存储a
  • 变量b:占24个字节,从8开始(该结构体内部最大为double8字节),此时min(8,24),即 8-31 存储b
  • 收尾工作:通过计算Mystruct2需要内存为31字节,但Mystruct2中最大成员需要8个字节,所以Mystruct2所需内存必须为8的整数倍32不足则补齐。 image.png

获取内存大小的三种方式

  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 很显然,属性的排列顺序不同会导致对象所占的内存大小 不同。

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

总结

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

  • 大部分的内存都是通过 固定的内存块进行读取,
  • 尽管我们在内存中采用了内存对齐的方式,但并不是所有的内存都可以进行浪费的,苹果会自动对属性进行重排,以此来优化内存
  • 对于一个对象来说,其真正的对齐方式 是 8字节对齐,8字节对齐已经足够满足对象的需求了
  • apple系统为了容错,采用的是16字节对齐的内存,主要是因为采用8字节对齐时,两个对象的内存会紧挨着,显得比较紧凑,而16字节比较宽松,利于苹果以后的扩展
  • class_getInstanceSize:是采用8字节对齐,参照的对象的属性内存大小
  • malloc_size:采用16字节对齐,参照的整个对象的内存大小,对象实际分配的内存大小必须是16的整数倍

相关文章

  • iOS底层探索-目录

    iOS底层探索001-alloc&init&new源码分析 iOS底层探索002-内存对齐 iOS底层探索003-...

  • iOS内存对齐分析

    什么是内存对齐? 在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、floa...

  • iOS内存对齐分析

    今天探索的是内存是如何分配,如何对齐的, 一般我们在开发时通常都会用到LLDB断点调试, 看看下图对JJPerso...

  • iOS - 内存对齐分析

    iOS 内存对其原则 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第⼀个数据成员放在...

  • 2.iOS底层学习之内存对齐

    学习了内存对齐之后的疑问?? 1.为啥要内存对齐?2.内存对齐的规则?3.内存对齐实例分析。 内存对齐的目的 上网...

  • iOS内存对齐

    这篇文章我们来探索一下iOS内存对齐的原理,在探索完内存对齐原理之后,你就会明白内存对齐的好处。 在讲述内存对齐时...

  • iOS底层探究 - 内存对齐

    目录1:内存对齐的原因2:内存对齐的规则3:结构体内存分配演练以及在iOS中对象成员的内存分配探索 一 :内存对齐...

  • iOS 内存对齐原则分析

    在分析内存对齐原则之前,我们先来分析一下在OC和C中,各种基本数据类型在32位或64位的操作系统中,他们所占的字节...

  • iOS内存分析上-图片加载内存分析

    iOS内存分析上-图片加载内存分析 iOS内存分析上-图片加载内存分析

  • iOS底层之内存对齐算法解析

    目前但凡一个iOS岗面试都会问个内存对齐问题,那么什么是字节对齐?成员变量对齐和对象内存对齐有什么区别?今天我来为...

网友评论

      本文标题:iOS - 内存对齐分析

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