OC底层02:内存对齐

什么是内存对齐

先来看一个例子

struct s1 {
  double a;
  int b;
  char c;
  short d;
}s1;
struct s2 {
  int a;
  double b;
  char c;
  short d;
}s2;

printf("%lu-%lu \n", sizeof(s1), sizeof(s2));

每种数据类型的大小可参考:


按照图计算,内存大小应该都为8(double)+4(int)+1(char)+2(short)=15,然后运行结果如图:

可见,系统内部是按照一定规则进行内存分配的,而这个规则就叫内存对齐。

内存对齐规则

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

2.结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。

3.结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍,不足的要补⻬。

struct s1 {
  double a; //8字节  0~7
  int b; //4字节 8是4的倍数,所以从8开始 8~11
  char c; //1字节 12是1的倍数, 12
  short d; //2字节 13不是2的倍数,14是,所以占14,15
}s1;
//总大小16字节,最大成员为double,16是8的倍数,所以最终结果为16

struct s2 {
  int a; //4字节 0~3
  double b; // 8字节 8~15
  char c; //1字节 16
  short d;//2字节 18~19
}s2;
//总大小20,最大成员为double,20不是8的倍数,需要往上加到8*3=24,所以最终结果为24

结构体嵌套

struct s3 {
    int a; //4
    struct s1 b;//最大成员double 8,从8开始 8~23
    struct s2 c;//最大成员double 8, 从24开始24~47
}s3;
//总大小48,最大成员为8,最终结果为48

为什么要使用内存对齐

因为内存中速度尤为重要,所以在读取中固定了读取大小,这样有利于提高读取速度,而苹果一般是16字节16字节进行读取(为什么是16字节不是8,因为一个类中包含isa占8个字节, 一个对象指针也是占8字节,所以苹果按16字节进行读取)
假如类的内容占24个字节,在进行读取时,第一次读取16个字节,还剩8个字节,第二次读取时,就会读取下一个类的8个字节,从而造成数据错误,而进行内存对齐后,必然是16的倍数,从而读到内容必然在一个类中。

你可能感兴趣的:(OC底层02:内存对齐)