对于大多数研究底层的程序员,对内存对其应该都不陌生,今天小生来献丑一波。程序员
内存对齐 应该是编译器的“管辖范围”。编译器为程序中的每一个“数据单元”安排在适当的位置上。
对于大部分研究过底层的程序员来讲,“内存对齐”对他们来讲都应该是“透明的”。
复制代码
因为本人文采很差,借用下百度百科的解释。数组
(很长,说实话,我也懒得看下去。。不要紧,后面我会举例解释)markdown
一个数据成员放在offset为0的地方,之后每一个数据成员存储的起始位置要 从该成员大小或者成员的子成员大小(只要该成员有子成员,好比说是数组, 结构体等)的整数倍开始(好比int为4字节,则要从4的整数倍地址开始存 储。 min(当前开始的位置mn) m=9 n=4 那么 9 10 11 12 、 就要从12开始存储数据结构
其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b 里有char,int ,double等元素,那b应该从8的整数倍开始存储.)oop
成员的整数倍.不足的要补⻬性能
我也知道你们这个表都知道,可是不把图啪上感受没有仪式感spa
上面罗里吧嗦的终于结束了。只看理论啥收获都没有感受,仍是不让代码验证解释比较痛快。code
我会经过结构体来讲明orm
注: {}表明解释说明 。
struct XGStruct1 {
double a; // 8{所占字节数} (0{开始位置}-7{结束位置}){所占字节位置}
char b; // 1{所占字节数} [8{开始位置} 1{所占字节数}] (8){存储字节位置}
int c; // 4{所占字节数} [9{开始位置} 4{所占字节数}] 9 10 11 (12 13 14 15){存储字节位置}
short d; // 2{所占字节数} [16{开始位置} 2{所占字节数}] (16 17){存储字节位置}
}struct1;
解释说明:
内存对齐规则1:开始位置必须是所占字节数的整数倍,才能开始存。
(举例:char b,因为开始位置是所占字节数的整数倍能够直接存,int c ,开始位置是从9,并非4的整数倍,因此从12开始存)
存储大小是:18{0-17}
因为结构体中存在double为最大字节数:8
(内存对齐规则3:所占内存必须是最大字节数的整数倍。因此必须是8的整数倍。18-->24)
因此所占内存大小是24.
复制代码
输出log确认下:
NSLog(@"%lu",sizeof(struct1));
log输出:24
复制代码
这个应该就比较形象了。内存
struct XGStruct2 {
int b; //4{所占字节数} [0{开始位置} 4{所占字节数}],(0 1 2 3){存储字节位置}
char c; //1{所占字节数} [4{开始位置} 1{所占字节数}], (4){存储字节位置}
short d; //2{所占字节数} [5{开始位置} 2{所占字节数}], 5 (6 7){存储字节位置}
short e; //2{所占字节数} [8{开始位置} 2{所占字节数}], (8 9){存储字节位置}
}struct2;
解释说明:
一、内存所占大小是 10(0-9)
二、内存中最大的字节是int(4),因此是4的整数倍。
理论结果:12
验证:
NSLog(@"%lu",sizeof(struct2));
输出:
12
复制代码
以上2个例子应该能够说明内存对其规则了。我相信你们也都懂了。那么,我们来一波进阶:结构体嵌套结构体。
继续用上面两个例子,而后加以改正:
struct XGStruct1 {
double a;
char b;
int c;
short d;
}struct1;
//已证
struct XGStruct2 {
int b;
char c;
short d;
short e;
}struct2;
//已证
咱们把XGStruct2 改变下,加入XGStruct1,变成XGStruct3:
struct XGStruct3 {
int b;
char c;
short d;
short e;
struct XGStruct1 xgs;
}struct3;
你们能够先想一想下,所占内存大小?
复制代码
解释了啊:
首先。咱们先经过规则,大概猜一下,会是什么样子的。。
而后我要开始验证了啊。。
先换一种好说明的写法
struct XGStruct3 {
int b; //4{所占字节数} [0{开始位置} 4{所占字节数}],(0 1 2 3){存储字节位置}
char c; //1{所占字节数} [4{开始位置} 1{所占字节数}], (4){存储字节位置}
short d; //2{所占字节数} [5{开始位置} 2{所占字节数}], 5 (6 7){存储字节位置}
short e; //2{所占字节数} [8{开始位置} 2{所占字节数}], (8 9){存储字节位置}
struct XGStruct4 {
double a;// [10 8] 10 11 12 13 14 15 (16 17 18 19 20 21 22 23)
int b; // [24 4] (24 25 26 27)
char c; // [28 1] (28)
short d; // [29 2] 29 (30 31)
}xgs;
}struct3;
所占大小是32 (0-31)
里面最大类型是double(8),又是8的倍数,那岂不是结果是32,
验证一波:
NSLog(@"%lu",sizeof(struct3));
输出:
32
还真是!!!!!
复制代码
你们能够经过多写点例子来验证。。看来内存对齐的规则仍是挺好用的。。