前言,以下内容基于php 7.4.3源码进行简单讲解,以加深自己对PHP的理解。由于本人也不是很厉害,如有错误欢迎通过邮箱联系我更正。
源码分析
首先找到php中的变量指针的结构体 zval
的定义
// Zend/zend_types.h
......
typedef struct _zval_struct zval;
......
接着找 _zval_struct
的定义
// Zend/zend_types.h
......
struct _zval_struct {
zend_value value; /* value */
union {
struct {
ZEND_ENDIAN_LOHI_3(
zend_uchar type, /* active type */
zend_uchar type_flags,
union {
uint16_t extra; /* not further specified */
} u)
} v;
uint32_t type_info;
} u1;
union {
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* cache slot (for RECV_INIT) */
uint32_t opline_num; /* opline number (for FAST_CALL) */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
uint32_t access_flags; /* class constant access flags */
uint32_t property_guard; /* single property guard */
uint32_t constant_flags; /* constant flags */
uint32_t extra; /* not further specified */
} u2;
};
......
u1 看上去比较像用来识别变量类型的一个结构, u2 应该是缓存方面使用的一些辅助的信息。所以研究垃圾回收应该就集中在研究 u2 和暂时还不了解结构的 zend_value 。所以接着研究一下 zend_value 这个结构体。回到上面的那个文件,找到 _zend_value 的定义部分。
// Zend/zend_types.h
......
typedef union _zend_value {
zend_long lval; /* long value */
double dval; /* double value */
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast;
zval *zv;
void *ptr;
zend_class_entry *ce;
zend_function *func;
struct {
uint32_t w1;
uint32_t w2;
} ww;
} zend_value;
......
注意上面代码的第11行,一个熟悉的单词 reference ,这里就会联想起之前 php5的时候也有类似的结构,所以应该就是它了
// Zend/zend_types.h
......
typedef struct _zend_reference zend_reference;
......
struct _zend_reference {
zend_refcounted_h gc;
zval val;
zend_property_info_source_list sources;
};
......
typedef struct _zend_refcounted_h {
uint32_t refcount; /* reference counter 32-bit */
union {
uint32_t type_info;
} u;
} zend_refcounted_h;
......
和之前的结构一样,很顺利的找到了上面的结构。 zend_refcounted_h 看到这个就可以知道了,php7对代码做了调整,但是实现原理应该还是一样的,后面的步骤其实就基本与php5相似了。
结合php5了解工作原理
参考内容
[1]php.net 垃圾回收机制