现代计算机中内存空间都是按照byte划分的,从理论上讲彷佛对任何类型的变量的访问能够从任何地址开始,但实际状况是在访问特定类型变量的时候常常在特 定的内存地址访问,这就须要各类类型数据按照必定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。bash
简单来说是由CPU架构形成的。好比arm64(ARM)
,x86(Intel、AMD)
, PowerPC(IBM)
等。 做为iOS Developer
,常见的有armv7
、armv7s
、arm64e
、arm64
、i386
、x86_64
。 CPU为了高效执行指令或者读取数据,不是按照字节读取的,而是根据数据将内存分块,每块的字节数都是偶数,如 2
、4
、8
、16
字节。每次读取都是一个固定的开销,减小内存存取次数将提高程序的性能。架构
每一个特定的平台上的编译器都有本身的默认对齐系数
(也叫对齐模数
)。咱们能够经过预编译命令#pragma pack(n),n=1,2,4,8,16
来改变这一系数,其中的n就是要指定的对齐系数
。Xcode的对齐系数就是8
,GCC对齐系数是4
。性能
咱们在了解内存对齐以前,先看看内存对齐的原则:spa
翻译一下就是翻译
接下来,须要用代码验证、查看对象alloc
时开辟的真实空间具体是多少。
能够用class_getInstanceSize(class)
、malloc_size()
来打印出对象的大小。code
struct StructOne {
char a; //1字节
double b; //8字节
int c; //4字节
short d; //2字节
} MyStruct1;
struct StructTwo {
double b; //8字节
char a; //1字节
short d; //2字节
int c; //4字节
} MyStruct2;
NSLog(@"%lu---%lu", sizeof(MyStruct1), sizeof(MyStruct2));
复制代码
获得的结果是24---16
。对象
StructOne
中a
为1字节,不够8个字节,而第二个成员为b为double
类型,为8个字节,因此b
能够被编译器单独读取,为了读取效率,不能够分割也不能和其余数据合并,因此要对a
进行7个字节补充,使其占用8个字节。c
为int类型,占用4个字节,d
为short类型,占用2个字节,c和d能够合并另外再对其进行2个字节的补充,使其占用8个字节。 这样就符合了内存对其原则,最后StructOne
占用的空间为(1+7)+8+(4+2+2)=24。StructTwo
中StructTwo
占用的空间为8+(1+2+4+1)=16。字节对齐是为了提高CPU执行效率产生的规则,原理是按照对齐系数对内存进行排列读取。在iOS中编译器帮咱们处理了这一问题,因此无需考虑,但在平常开发中若是在写C语言的代码时,就能够利用字节对齐的规则进行生命变量,以提高效率。内存