現代計算機中內存空間都是按照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語言的代碼時,就能夠利用字節對齊的規則進行生命變量,以提高效率。內存