2、iOS底层分析—内存对齐原理

内存对齐

                                                         

1、CPU 存取原理

CPU 并不是以字节为单位存取数据的。CPU把内存当成是一块一块的,块的大小可以是24816字节大小,因此CPU在读取内存时是一块一块进行读取的。每次内存存取都会产生一个固定的开销,减少内存存取次数将提升程序的性能。所以 CPU 一般会以 2/4/8/16/32 字节为单位来进行存取操作。我们将上述这些存取单位也就是块大小称为(memory access granularity)内存存取粒度。

例如:在一个存取粒度为 4 字节的内存中,先从地址 0 读取 4 个字节到寄存器,然后从地址 1 读取 4 个字节到寄存器。

当从地址 0 开始读取数据时,是读取对齐地址的数据,直接通过一次读取就能完成。当从地址 1 读取数据时读取的是非对齐地址的数据。需要读取两次数据才能完成。

而且在读取完两次数据后,还要将 0-3 的数据向上偏移 1 字节,将 4-7 的数据向下偏移 3 字节。最后再将两块数据合并放入寄存器。

对一个内存未对齐的数据进行了这么多额外的操作,这对 CPU 的开销很大,大大降低了CPU性能。所以有些处理器才不情愿为你做这些工作。

 

内存对齐原则

1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第

一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要

从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,

结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存

储。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从

其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b

里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大

成员的整数倍.不足的要补齐。

例:

1

struct StructTwo {

    double b;       //8字节

    char a;         //1字节

    short d;        //2字节 + 1

    int c;         //4字节

} MyStruct3;

 

b(8)最大是8,不足8的补齐。a(1)后面是d(2), 加起来是3,后面在有的话需要在2的倍数的起始位置开始也就是4。所以c(4)和a、d排在一起。

 b(8) +  [a(1)+d(2)+1+c(4)]= 16;

 

2

struct StructTwo {

    double b;       //8字节

    char a;         //1字节

    int c;         //4字节 +3

    short d;        //2字节 +6

} MyStruct2;

 

MyStruct2

b(8),最大是8,不足8的补齐。a(1)后面是c(4), 加起来是5,后面在有的话需要在4的倍数的起始位置开始也就是8,满了。所以d(2)自己再补齐6。

 b(8) +  [a(1)+c(4)+3] + d(2)+6 = 24;

 

3

struct StructTwo {

char a;         //1字节

struct MyStruct2; //24字节   8-31

    int c;         //4字节         32-35

    short d;        //2字节 +2     36-37

} MyStruct3;

 

MyStruct3

MyStruct2 中的 b(8),最大是8,不足8的补齐。a(1) 后面 结构体所以a(1)自己补齐+7。 MyStruct2 结构体是24 c(4) + d(2)=6 再补齐2。

 [a(1)+7] + 24 + [c(4)+ d(2)+2] = 40;

 

4

struct StructTwo {

    int c;         //4字节

} MyStruct4;

 

struct StructTwo {

char a;         //1字节

struct MyStruct4; //4字节   8-31

    int c;         //4字节         32-35

    short d;        //2字节 +2     36-37

} MyStruct5;

 

MyStruct5

MyStruct4 中的 c(4),最大是4,不足4的补齐。同时要满足从4的整数倍开始排列。a(1) 后面 还有7字节,MyStruct4  4字节开始排,同时自身是4字节,所以a(1)+3+ MyStruct4 =8 c(4) + d(2)=6 再补齐2。

 [a(1)+3+4] + [c(4)+ d(2)+2] = 16;

 

发布了83 篇原创文章 · 获赞 12 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/shengdaVolleyball/article/details/104029096