對於大多數研究底層的程序員,對內存對其應該都不陌生,今天小生來獻醜一波。程序員
內存對齊 應該是編譯器的「管轄範圍」。編譯器爲程序中的每一個「數據單元」安排在適當的位置上。
對於大部分研究過底層的程序員來講,「內存對齊」對他們來講都應該是「透明的」。
複製代碼
因爲本人文采很差,借用下百度百科的解釋。數組
(很長,說實話,我也懶得看下去。。不要緊,後面我會舉例解釋)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
還真是!!!!!
複製代碼
你們能夠經過多寫點例子來驗證。。看來內存對齊的規則仍是挺好用的。。