iOS开发之runtime(26):libmalloc入门
2019-03-31 本文已影响50人
kyson老师
本系列博客是本人的源码阅读笔记,如果有 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入门