天天看點

iOS之記憶體管理-位元組對齊

Mystruct1 與 Mystruct2 資料成員的順序不同,為什麼會導緻記憶體配置設定的大小不同呢?

根據這條原則,上面的 Mystruct1 中

成員 a 占 1 個位元組, 從 0 的位置開始

成員 b 占 8 個位元組,挨 0 + 1 最近的 8 的整數倍是8,是以 b 從 8 的位置開始

成員 c 占 4 個位元組,挨 8 + 8 最近的 4 的整數倍是16,是以 c 從 16 的位置開始

成員 d 占 2 個位元組,挨 16 + 4 最近的 2 的整數倍是20,是以 d 從 20 的位置開始

一共是占 22 個位元組,8 位元組對齊,一定要是8的倍數,不足要補齊,是以是 24 個位元組

上面的 Mystruct2 中

成員 a 占 8 個位元組, 從 0 的位置開始

成員 b 占 4 個位元組,挨 0 + 8 最近的 4 的整數倍是8,是以 b 從 8 的位置開始

成員 c 占 2 個位元組,挨 8 + 4 最近的 2 的整數倍是12,是以 c 從 12 的位置開始

成員 d 占 1 個位元組,挨 12 + 2 最近的 1 的整數倍是14,是以 d 從 14 的位置開始

一共是占 15 個位元組

根據這條原則,上面的 Mystruct1 中,占 22 個位元組,必須是最大成員 (double b )的整數倍,也就是8的整數倍,是以占24個位元組

根據這條原則,上面的 Mystruct2 中,占 15 個位元組,必須是最大成員 (double b )的整數倍,也就是8的整數倍,是以占16個位元組

上面的 Mystruct3 中,成員 a,b,c,d 的記憶體配置設定和 Mystruct2 是一緻的, 占15個位元組;

成員 e 是 Mystruct1 類型,上面也計算過是占24個位元組。

成員e 的内部最大成員是 double b, 占8位元組。

根據上面的規則,成員 e 的起始位置為子結構體中的最大成員(double b)的整數倍,挨着 15 最近的 8 的倍數是 16,是以 成員 e 從16開始,占24個位元組。Mystruct3 所占記憶體大小為 16 + 24 = 40 ,正好是最大成員 8 的倍數。是以成員 e 占40位元組

由上面的栗子可以知道,結構體的資料成員順序會影響結構體類型占用的記憶體大小。

由此蘋果中采用屬性重排的方案。蘋果會自動重排屬性的順序,将占用不足 8 位元組的成員挨在一起,湊滿 8 位元組,以達到優化記憶體的目的。

下面舉個栗子🌰來證明下屬性重排的存在:定義一個 Person類,屬性類型大小的順序是混亂的。

iOS之記憶體管理-位元組對齊
iOS之記憶體管理-位元組對齊

從位址的列印結果中可以看出,age、isGirl、isBoy三個屬性被放在了一起,蘋果的确進行了自動屬性重排,以優化記憶體。

xcode中預設的對齊系數是8,即8位元組對齊。可以通過預編譯指令<code>#pragma pack(n)</code>,n= 1,2,4,8,16 來改變這個系數。

iOS之記憶體管理-位元組對齊

sizeof(類型),擷取類型占用的位元組數

class_getInstanceSize,擷取執行個體對象(即執行個體對象的成員變量)實際占用的位元組數,從源碼看是采用 <code>8位元組</code> 對齊

malloc_size,系統實際配置設定的記憶體大小(位元組數)。采用<code>16位元組對齊</code>,參照的整個對象的記憶體大小,對象實際配置設定的記憶體大小必須是16的整數倍. 由于記憶體對齊,實際配置設定的記憶體會大于等于實際占用的記憶體

計算<code>類型占用的記憶體大小</code>,其中可以放 <code>基本資料類型、對象、指針</code>

對于類似于<code>int</code>這樣的<code>基本資料</code>而言,<code>sizeof</code>擷取的就是<code>資料類型占用的記憶體大小</code>,不同的資料類型所占用的記憶體大小是不一樣的.

而對于類似于NSObject定義的<code>執行個體對象</code>而言,其<code>對象類型</code>的本質就是<code>一個結構體(即 struct objc_object)的指針</code>,是以<code>sizeof(objc)</code>列印的是<code>對象objc的指針大小</code>,我們知道<code>一個指針的記憶體大小是8</code>,是以<code>sizeof(objc) 列印是 8</code>。注意:這裡的8位元組與<code>isa</code>指針一點關系都沒有!!!)

iOS之記憶體管理-位元組對齊
iOS之記憶體管理-位元組對齊
iOS之記憶體管理-位元組對齊