iOS底層之內存對齊

一、什么是內存對齊?

內存對齊是一種在計算機內存中排列數(shù)據(jù)(表現(xiàn)為變量的地址)、訪問數(shù)據(jù)(表現(xiàn)為CPU讀取數(shù)據(jù))的一種方式。

它包含了兩種相互獨立又相互關聯(lián)的部分:基本數(shù)據(jù)對齊結構體數(shù)據(jù)對齊 。

二、為什么要進行內存對齊?

1、平臺原因(移植原因):不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。
2、性能原因:數(shù)據(jù)結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在于,為了訪問未對齊的內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問。

說的通俗點就是方便讀取,速度快。

三、內存對齊原則:

1、數(shù)據(jù)成員對?規(guī)則:結構(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個數(shù)據(jù)成員放在offset為0的地方,以后每個數(shù)據(jù)成員存儲的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是數(shù)組,結構體等)的整數(shù)倍開始(比如int為4字節(jié),則要從4的整數(shù)倍地址開始存儲)。下面咱們用(m, n)來理解一下,其中m為內存的起始位置,n為當前成員的內存大小,m,n一定要滿足m%n==0。

2、結構體作為成員:如果一個結構里有某些結構體成員,則結構體成員要從其內部最大元素大小整數(shù)倍地址開始存儲(struct a里存有struct b,b里有char、int 、double等元素,那b應該從8的整數(shù)倍開始存儲。)

3、收尾工作:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員整數(shù)倍,不足的要補?。

各位同學,能理解上面這些原則嗎,反正光看文字我是理解不了,沒關系,咱們是程序員,咱們可以用代碼來解釋。

四、數(shù)據(jù)成員結構體內存分析

struct Struct1 {
    double a;   // 8
    char b;     // 1
    int c;      // 4
    short d;    // 2
}struct1;

struct Struct2 {
    double a;   //8
    int b;      //4
    char c;     //1
    short d;    //2
}struct2;
NSLog(@"結果為:%lu-%lu",sizeof(struct1),sizeof(struct2));

咱們來看下打印結果

 結果為:24-16

為什么會出現(xiàn)不同的結果呢,咱們來分析一下,不過在分析代碼之前呢咱們先看下各個類型的內存大小

數(shù)據(jù)類型內存大小表

下面咱們來分析一下Struct1的結果:

  • 首先Struct1中以double開始,在內存中的地址是0~7
  • 接下來是char,char占用內存大小為1字節(jié),此時在內存中的起始地址8,此時8%1==0表示可以從此位置開始存放char,在內存中的地址是8。
  • 然后是intint占用內存大小為4字節(jié),此時在內存中的起始位置9,但是現(xiàn)在9%4 != 0,所以此時只能向后移,找到一個能被4整除的數(shù),下一個能被4整除的數(shù)是12,所以此時int的起始位置為12,長度為4字節(jié),在內存中的地址是12~15。
  • 最后是short,short占用內存2字節(jié),此時內存中的起始位置16,16%2==0成立,所以short在內存中的起始位置是16,長度為2,在內存中的地址是16~17。
    由上述結果可得Struct1在內存中占用18個字節(jié),根據(jù)內存對齊第三條原則,Struct1內部最大成員為double8字節(jié),所以Struct1最終占用的內存大小為24字節(jié)。由此可以得出下圖:
    Struct1內存分布圖

同理,我們再來分析一下Struct2的結果:

  • 首先Struct2中以double開始,在內存中的地址是0~7
  • 然后是int,int占用內存大小為4字節(jié),此時在內存中的起始位置88%4 == 0等式成立,所以此時int的起始位置為8,長度為4字節(jié),在內存中的地址是8~11。
  • 接下來是char,char占用內存大小為1字節(jié),此時在內存中的起始地址12,此時12%1==0等式成立表示可以從此位置開始存放char,在內存中的地址是12。
  • 最后是shortshort占用內存2字節(jié),此時內存中的起始位置13,13%2==0等式不成立,需要向后移,找到一個能被2整除的數(shù),所以short在內存中的起始位置是14,長度為2,在內存中的地址是14~15
    有上述結果可得Struct2在內存中占用16個字節(jié),根據(jù)內存對齊原則第三條,Struct2內部最大成員為double8字節(jié),所以Struct2最終占用的內存大小為16字節(jié)。由此可得出下圖:
    Struct2內存分布圖

這就是Struct1Struct2結果不同的原因。
由此我們可以得出結論:結構體所占內存大小與結構體內部的成員變量的順序有關。

五、嵌套結構體內存分析

struct Struct3 {
    double a;              //8
    char b;                //4
    struct Struct1 c;      //24
    short d;               //2
}struct3;

struct Struct4 {
    double a;              //8
    char b;                //1
    short c;               //2
    struct Struct2 d;      //16
}struct4;
NSLog(@"結果為:%lu-%lu",sizeof(struct3),sizeof(struct4));

咱們來看下打印結果

結果為:48-32

我們來分析下Struct3的結果:

  • 首先Struct3中以double開始,在內存中的地址是0~7。
  • 接下來是charchar占用內存大小為1字節(jié),此時在內存中的起始地址8,此時8%1==0等式成立表示可以從此位置開始存放char,在內存中的地址是8,在內存中的地址是8
  • 然后是結構體Struct1,由上面的結論得知Struct1的大小為24字節(jié),此時在內存中的起始地址9,根據(jù)內存對齊原則第二條得知需從其內部最大元素大小整數(shù)倍地址開始存儲,Struct1中最大的為double8字節(jié),9%8 == 0不成立,所以取最近的一個能被8整除的數(shù)為16,所以Struct1在內存中的起始位置為16,長度為24,在內存中的地址是16~39。
  • 最后是shortshort占用內存2字節(jié),此時內存中的起始位置4040%2==0等式成立,起始位置是40,長度為2,在內存中的地址是40~41。
    有上述結果可得Struct3在內存中占用42個字節(jié),根據(jù)內存對齊原則Struct3內部包括子成員Struct1內部最大成員為double8字節(jié),所以Struct3最終占用的內存大小為48字節(jié)。由此可得出下圖:
    Struct3內存分布圖

我們來分析下Struct4的結果:

  • 首先Struct4中以double開始,在內存中的地址是0~7。
  • 接下來是char,char占用內存大小為1字節(jié),此時在內存中的起始地址8,此時8%1==0等式成立表示可以從此位置開始存放char,在內存中的地址是8,在內存中的地址是8。
  • 然后是short,short占用內存2字節(jié),此時內存中的起始位置9,9%2==0等式不成立,其后能被2整除的數(shù)為10,那么起始位置是10,長度為2,在內存中的地址是10~11。
  • 最后是結構體Struct2,由上面的結論得知Struct2的大小為16字節(jié),此時在內存中的起始地址12,根據(jù)內存對齊原則第二條得知需從其內部最大元素大小整數(shù)倍地址開始存儲,Struct2中最大的為double8字節(jié),12%8 == 0不成立,所以取最近的一個能被8整除的數(shù)為16,所以Struct2在內存中的起始位置為16,長度為16,在內存中的地址是16~31
    有上述結果可得Struct4在內存中占用32個字節(jié),根據(jù)內存對齊原則,Struct4內部包括子成員Struct1內部最大成員為double8字節(jié),所以Struct4最終占用的內存大小為32字節(jié)。由此可得出下圖:
    Struct4內存分布圖

以上就是我對內存對齊原則的理解,如果有不同意見的同學歡迎留言給我。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容