内存对齐

2019-12-22  本文已影响0人  redye

内存对齐,或者说字节对齐,是代码编译后在内存的布局与使用方式。现代计算机一般是32比特或64比特地址对齐,如果要访问的变量没有对齐,可能会触发总线错误。参考维基百科

什么是内存对齐

即某个地址A满足是n的倍数,其中n是2的幂次方(如1、2、4、8等等)。如果用二进制表示的话,那么 A的末尾至少有log2n个0。当我们说到某个变量是n字节对齐的时候,其意思是指这个变量的地址是对齐的。

内存对齐的意义

从我们编写的程序来看,CPU好像可以访问内存中的任意位置;但是实际上CPU往往是按照块为基本单位访问内存的。如果某个变量的起始地址位于某个块的的起始处,则只需较少的次数便能完成读取。 比如在某个CPU中,其每次取内存的大小为8字节,对于一个8字节的long类型变量,如果该变量的地址是8的倍数,那么每次load这个long变量只需要一次操作。如果不是8的倍数则需要两次,影响效率。

内存对齐的原则

内存对齐的例子

我们以 64 位架构,即 8 字节对齐:

struct {
    char a;     // 1 byte   offset = 0x00  0x00~0x07 8字节
    double b;   // 8 bytes  地址为8的倍数 offset = 0x08 0x08~0x0f 8字节
    short c;    // 2 bytes  地址为2的倍数 offset = 0x10 0x10~0x11 2字节
    char d;     // 1 byte   地址为1的倍数 offset = 0x12 0x12 1字节
} x; // 地址为8的倍数,0x00~0x17

struct {
    double b;   // 8 bytes  0x00~0x07
    char a;     // 1 byte   0x08
    char d;     // 1 byte   0x09
    short c;    // 2 bytes  0x0a~0x0b
} y;  // 0x00~0x0f

NSLog(@"%lu - %lu", sizeof(x), sizeof(y)); //24 - 16

为什么两次输出的结果不一样的原因就是内存对齐的存在。

如果不考虑内存对齐,那么两次输出的就都应该是 12。

结构体的大小受其成员变量分布的影响。

address-align.png
上一篇 下一篇

猜你喜欢

热点阅读