本系列博客是本人的源碼閱讀筆記,如果有 iOS 開發者在看 runtime 的,歡迎大家多多交流。爲了方便討論,本人新建了一個微信羣(iOS技術討論羣),想要加入的,請添加本人微信:zhujinhui207407,【加我前請備註:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,歡迎一起討論
本文完整版詳見筆者小專欄:https://xiaozhuanlan.com/runtime
背景
maptable 中創建函數如下:
NXMapTable *NXCreateMapTableFromZone(NXMapTablePrototype prototype, unsigned capacity, void *z) {
NXMapTable *table = (NXMapTable *)malloc_zone_malloc((malloc_zone_t *)z,
之前我們沒有說過 malloc_zone_malloc 這個函數,今天我們大概瞭解一下。
分析
函數 NXCreateMapTableFromZone 被調用的時機爲:
NXMapTable *NXCreateMapTable(NXMapTablePrototype prototype, unsigned capacity) {
return NXCreateMapTableFromZone(prototype, capacity, malloc_default_zone());
}
因此,我們這裏調用 malloc_zone_malloc 將參數代入,可以改寫爲:
malloc_zone_malloc(malloc_default_zone(),sizeof(NXMapTable));
我們看一下該方法的定義:
void *
malloc_zone_malloc(malloc_zone_t *zone, size_t size)
{
MALLOC_TRACE(TRACE_malloc | DBG_FUNC_START, (uintptr_t)zone, size, 0, 0);
void *ptr;
if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
internal_check();
}
if (size > MALLOC_ABSOLUTE_MAX_SIZE) {
return NULL;
}
ptr = zone->malloc(zone, size); // if lite zone is passed in then we still call the lite methods
if (malloc_logger) {
malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0);
}
MALLOC_TRACE(TRACE_malloc | DBG_FUNC_END, (uintptr_t)zone, size, (uintptr_t)ptr, 0);
return ptr;
}
可見正常情況下應該會進入到代碼塊:
ptr = zone->malloc(zone, size);
中。
也就是說
malloc_zone_malloc(malloc_default_zone(),sizeof(NXMapTable));
最終調用的調用結果是:
malloc_default_zone()->malloc(zone, size);
那麼
- 什麼是 default zone ?
- 除了 default zone 還有其他什麼 zone ?
要解決這個問題,我們先抽絲剝繭,看看這個 malloc_default_zone() 的實現是怎麼樣的。源碼如下:
malloc_zone_t *
malloc_default_zone(void)
{
return default_zone;
}
而 default_zone 的實現如下:
static virtual_default_zone_t virtual_default_zone
__attribute__((section("__DATA,__v_zone")))
__attribute__((aligned(PAGE_MAX_SIZE))) = {
NULL,
NULL,
default_zone_size,
default_zone_malloc,
default_zone_calloc,
default_zone_valloc,
default_zone_free,
default_zone_realloc,
default_zone_destroy,
DEFAULT_MALLOC_ZONE_STRING,
default_zone_batch_malloc,
default_zone_batch_free,
&default_zone_introspect,
10,
default_zone_memalign,
default_zone_free_definite_size,
default_zone_pressure_relief,
default_zone_malloc_claimed_address,
};
static malloc_zone_t *default_zone = &virtual_default_zone.malloc_zone;
棒!這個 __attribute__((section(
是不是特別熟悉!!!不熟悉的回顧文章:
iOS開發之runtime(16):設置/獲取section數據詳解
也就是說,virtual_default_zone 是在App啓動的時候就已經設置好值了。關於 default zone 筆者就討論到這裏了,更深層次的就不研究了,大家有興趣可以再去研究 libmalloc 的源碼。
完整版詳見筆者小專欄:iOS開發之runtime(26):libmalloc入門