为了账号安全,请及时绑定邮箱和手机立即绑定

PHP源码的疑问

PHP源码的疑问

PHP
宝慕林4294392 2018-08-18 16:25:00
看到两段代码:// 第一段代码int symbols;do {     symbols = zend_hash_num_elements(&EG(symbol_table));     zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC); } while (symbols != zend_hash_num_elements(&EG(symbol_table)));// 第二段代码zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);这段代码的意思是不是 反向遍历 symbol_table ,然后把每个需要执行析构函数的 zval 扔到 TSRMLS_CC 里,这家伙就是一个数组了,然后作为 zend_objects_store_call_destructors 函数的参数,zend_objects_store_call_destructors函数内部再遍历它(TSRMLS_CC)?是这样吗?谢谢诸位
查看完整描述

1 回答

?
翻阅古今

TA贡献1780条经验 获得超5个赞

1.反向遍历全局符号表
2.对符号表中的每一个元素应用zval_call_destructor函数
3.判断符号表中值的类型,如果是对象,则将其zval置为IS_UNDEF
4.遍历对象栈,逐个执行对象的析构函数

判断符号表中的元素的类型,如果是对象,则返回ZEND_HASH_APPLY_REMOVE,后续清理相应的zval,有相应的析构函数则执行static int zval_call_destructor(zval *zv) /* {{{ */{    if (Z_TYPE_P(zv) == IS_INDIRECT) {
        zv = Z_INDIRECT_P(zv);
    }    if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {        return ZEND_HASH_APPLY_REMOVE;
    } else {        return ZEND_HASH_APPLY_KEEP;
    }
}

更新---------------------------------------------
在symbol的上一段,设置了符号表的析构函数

if (CG(unclean_shutdown)) {
    EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
}

在反向遍历符号表的过程中,如果引用计数减为0,对其存储的zval执行析构函数
这个函数又调用了zend_objects_store_del
功能是先执行对象的析构函数,然后释放对象占用的内存


查看完整回答
反对 回复 2018-08-19
  • 1 回答
  • 0 关注
  • 538 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信