1、內存對齊原理算法
先給出一段代碼,並打印對象的存儲空間內容數組
由 0x0000001200006261 能夠引出內存優化---內存拼接和內存對齊。數據結構
內存對齊原則(借鑑大神的理論):優化
1:數據成員對⻬規則:結構(struct)(或聯合(union))的數據成員,第 一個數據成員放在offset爲0的地方,之後每一個數據成員存儲的起始位置要 從該成員大小或者成員的子成員大小(只要該成員有子成員,好比說是數組, 結構體等)的整數倍開始(好比int爲4字節,則要從4的整數倍地址開始存 儲。3d
2:結構體做爲成員:若是一個結構裏有某些結構體成員,則結構體成員要從 其內部最大元素大小的整數倍地址開始存儲.(struct a裏存有struct b,b 裏有char,int ,double等元素,那b應該從8的整數倍開始存儲.)指針
3:收尾工做:結構體的總大小,也就是sizeof的結果,.必須是其內部最大 成員的整數倍.不足的要補⻬。cdn
給出一段代碼說明對象
2、對象申請內存 VS 系統開闢內存blog
獲取內存空間大小的兩個API:排序
class_getInstanceSize:傳入一個類對象返回一個對象的實例至少申請的內存,等價於sizeof;對象裏面的屬性空間8字節對齊
malloc_size:返回系統實際分配的內存大小;系統開闢的空間16字節對齊
根據上圖提出兩個問題:
1)當類裏沒有任何屬性的狀況下,爲何class_getInstanceSize 獲取的內存大小要比 malloc_size 獲取到的大8?
先給出class_getInstanceSize的調用流程及最終源碼 class_getInstanceSize -> alignedInstanceSize -> word_align
此圖可看出對象裏的屬性爲 8 字節對齊。
再看 alloc 計算 size 源碼
2)爲何當類裏有屬性而且大於屬性內存大於16字節的時候,class_getInstanceSize 獲取的內存是8字節對齊,malloc_size 獲取到內存是16字節對齊?
由於 alloc 建立對象並申請內存的時候的流程(關於alloc調用流程,OC 對象原理(1)有提到)會到達, _class_createInstanceFromZone 這個方法(下圖)
3、calloc 原理探索
1)先下載並配置 malloc 源碼
2)追蹤流程計算size並返回的地方
calloc調用流程:calloc -> malloc_zone_calloc -> default_zone_calloc -> nano_calloc -> _nano_malloc_check_clear -> segregated_size_to_fit
segregated_size_to_fit 返回了 slot_bytes,能夠推斷這就是肯定計算size大小的算法了
如今就回答上面的第二個問題:由於前面的8字節對齊的參照物是對象裏面的屬性,而屬性的類型最大也是8字節,因此屬性內存大小8字節對齊並不會有什麼問題。可是系統分配的內存大小爲16字節對齊,是由於此時參考的因素是整個對象,要是8字節對齊就很大內存溢出的風險。