zend_gc_globals结构体
|
|
说明:
gc_enabled 是否开启了GC
gc_active 是否GC正在运行
gc_full GC缓冲区是否已经满le
buf 预分配总的缓冲区大小
roots 可能需要回收对象列表
unused 未使用的缓存区
first_unused 未使用的缓冲区的第一个元素
last_unused 未使用的缓冲区的最后一个元素
to_free 垃圾列表
next_to_free 指一个垃圾列表元素
gc_runs GC运行次数
collected 是否垃圾收集完成
additional_buffer 其它缓冲区
GC初始化gc_globals
gc_globals_ctor -> ts_allocate_id -> gc_globals_ctor_ex
```
ZEND_API void gc_globals_ctor(void)
{
#ifdef ZTS
ts_allocate_id(&gc_globals_id, sizeof(zend_gc_globals), (ts_allocate_ctor) gc_globals_ctor_ex, (ts_allocate_dtor) root_buffer_dtor);
#else
gc_globals_ctor_ex(&gc_globals);
#endif
}
参数说明:
rsrc_id 全局资源id (int型)
size 资源大小
ctor 构造器
dtor 析构器
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{
int i;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, “Obtaining a new resource id, %d bytes”, size));
/ 加互斥锁 /
tsrm_mutex_lock(tsmm_mutex);
/ 生成全局资源id /
rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, “Obtained resource id %d”, rsrc_id));
/ 注册新的资源到全局资源表 /
if (resource_types_table_size < id_count) { / 如果资源表的大小太小,则调整资源表的大小 /
/ 扩展资源表的内存空间 /
resource_types_table = (tsrm_resource_type ) realloc(resource_types_table, sizeof(tsrm_resource_type)id_count);
/ 如果内存分配失败,解锁并返回 /
if (!resource_types_table) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, “Unable to allocate storage for resource”));
rsrc_id = 0;
return 0;
}
/ 如果分配成功,则修改资源表的大小 /
resource_types_table_size = id_count;
}
/ 注册全局资源对象 /
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(rsrc_id)].size = size;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(rsrc_id)].ctor = ctor;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(rsrc_id)].dtor = dtor;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(rsrc_id)].done = 0;
/ 遍历线程表,同步全局资源到各个线程对象 /
for (i=0; i
int j;
/ 扩展线程资源数据内存空间 /
p->storage = (void ) realloc(p->storage, sizeof(void )id_count);
/ 新增资源分配内存空间 /
for (j=p->count; j
if (resource_types_table[j].ctor) {
/ 调用构造器,初始化gc_globals对象 /
resource_types_table[j].ctor(p->storage[j]);
}
}
/ 修改线程资源数量 /
p->count = id_count;
}
/ 同步下一个线程对象 /
p = p->next;
}
}
/ 资源初始化完毕,解锁 /
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, “Successfully allocated new resource id %d”, rsrc_id));
/ 全局资源id /
return rsrc_id;
}
/ 初始化gc_globals对象 /
static void gc_globals_ctor_ex(zend_gc_globals *gc_globals)
{
gc_globals->gc_enabled = 0;
gc_globals->gc_active = 0;
gc_globals->buf = NULL;
gc_globals->roots.next = &gc_globals->roots;
gc_globals->roots.prev = &gc_globals->roots;
gc_globals->unused = NULL;
gc_globals->next_to_free = NULL;
gc_globals->to_free.next = &gc_globals->to_free;
gc_globals->to_free.prev = &gc_globals->to_free;
gc_globals->gc_runs = 0;
gc_globals->collected = 0;
gc_globals->additional_buffer = NULL;
#if GC_BENCH
gc_globals->root_buf_length = 0;
gc_globals->root_buf_peak = 0;
gc_globals->zval_possible_root = 0;
gc_globals->zval_buffered = 0;
gc_globals->zval_remove_from_buffer = 0;
gc_globals->zval_marked_grey = 0;
#endif
}