iOS 底層原理 文章彙總
在iOS-底層原理 02:alloc & init & new 源碼分析文章中,
alloc
有3個核心操作,其中一個就是
calloc
,即申請記憶體,這就是今天需要探索的内容,其實探索的本質也是為了驗證
ios中對象中實際的對齊方式是8位元組對齊
objc4中分析calloc 源碼
- 首先從alloc進入objc的源碼,找到
操作,涉及的方法順序是obj = (id)calloc(1, size);
alloc --> _objc_rootAlloc --> callAlloc --> _objc_rootAllocWithZone --> _class_createInstanceFromZone
這裡calloc的探索需要切換到
libmalloc
源碼中,可以在這裡下載下傳最新版,接着往下走
libmalloc中分析calloc源碼
- 在可編譯的libmalloc中定義一個可編譯的target,在main中使用
建立一個指針calloc
- 進入calloc的源碼實作,其中的關鍵代碼在于
1713行的 malloc_zone_calloc
- 其中
是一個預設的zone,目的就是引導程式進入一個建立真正default_zone
的流程zone
- 其中
- 進入
的源碼實作,關鍵代碼是1441行的malloc_zone_calloc
zone->calloc
- 其中
傳入的zone 就是 上一步中的zone->calloc
default_zone
- 這個關鍵代碼的
就是目的
申請一個指針,并将指針位址傳回
- 其中
- 在進入
的源碼,發現是一個zone->alloc
的聲明,到此,源碼就無法繼續跟進了calloc
那麼重點來了!!!想要繼續跟進源碼,可以通過以下方式:
- 在
中的關鍵代碼,即malloc_zone_calloc
處,加一個斷點,然後運作ptr = zone->calloc(zone, num_items, size);
- 斷點斷在 ptr位置,想要進入zone->calloc源碼實作,有兩種方式:
- 按住
+control
,進入step into
的源碼實作calloc
- ,然後通過lldb指令
查找源碼實作,通過列印得知p zone->callocde
的源碼實作在zone->calloc
方法,然後全局搜尋default_zone_calloc
方法,找到具體實作default_zone_calloc
- 按住
- 進入calloc的源碼實作,其中主要由兩部分操作
- 建立真正的
,即zone
方法runtime_default_zone
- 使用真正的
進行zone
calloc
- 建立真正的
斷點斷在zone的位置,此時通過lldb指令
p zone->alloc
是不行的,因為
zone
還
沒有指派
zone 未指派的驗證
- 進入
的源碼實作runtime_default_zone
- 進入
的源碼實作,通過檢視inline_malloc_default_zone
的值發現是malloc_zones
,可以得出,此時的NULL
zone還未指派
繼續跟蹤源碼
- 回到
方法,繼續執行,斷在default_zone_calloc
部分,此時同樣可以通過上述的兩種方法任選其一進入 calloc的源碼實作zone->calloc
nano_calloc
- 進入
方法,其中的關鍵代碼是 878,此時的p是pointer表示nano_calloc
和前面的 ptr一樣,主要由兩部分邏輯指針
- 如果要開辟的空間小于
,則進行則進行NANO_MAX_SIZE
的nanozone_t
malloc
- 反之,就進行
流程helper_zone
- 如果要開辟的空間小于
- 進入
源碼,将if else 折疊,看主流程_nano_malloc_check_clear
- 其中
就是指針記憶體開辟算法,目的是找到合适的記憶體并傳回segregated_next_block
-
是加密算法的slot_bytes
(其目的是為了讓加密算法更加安全,本質就是一串自定義的數字)鹽
- 其中
- 進入
加密算法源碼, 通過算法邏輯,可以看出,其本質就會16位元組對齊算法segregated_size_to_fit
#define SHIFT_NANO_QUANTUM 4
#define NANO_REGIME_QUANTA_SIZE (1 << SHIFT_NANO_QUANTUM) // 16
static MALLOC_INLINE size_t
segregated_size_to_fit(nanozone_t *nanozone, size_t size, size_t *pKey)
{
size_t k, slot_bytes;
//k + 15 >> 4 << 4 --- 右移 + 左移 -- 後4位抹零,類似于16的倍數,跟 k/16 * 16一樣
//---16位元組對齊算法,小于16就成0了
if (0 == size) {
size = NANO_REGIME_QUANTA_SIZE; // Historical behavior
}
k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM; // round up and shift for number of quanta
slot_bytes = k << SHIFT_NANO_QUANTUM; // multiply by power of two quanta size
*pKey = k - 1; // Zero-based!
return slot_bytes;
}
在iOS-底層原理 05:記憶體對齊原理文末,已經提及過該算法,這裡不再過多說明
- 回到
方法,進入_nano_malloc_check_clear
源碼,這個方法主要就是segregated_next_block
擷取記憶體指針
- 但是如果是第一次走到
函數,band不存在,緩存也不會存在,是以會調用segregated_next_block
,來開辟新的segregated_band_grow
band
- 但是如果是第一次走到
- 進入
源碼,主要是開辟新的bandsegregated_band_grow
先記錄libmalloc源碼中malloc分析的思路,需要時間研究源碼,後續再補充完善!!!
參考連結
- iOS 進階之美(六)—— malloc分析