PHP是如何做垃圾回收的(图文)【PHP教程】

!
也想出现在这里? 联系我们
信息

PHP是如何做垃圾回收的(图文),第1张

概述PHP是如何做垃圾回收的(图文

PHP是如何做垃圾回收的?

包含 PHP 5 与 PHP7 的变量实现和垃圾回收的对比

变量的实现

PHP 的变量是弱类型的,可以表示整数、浮点数、字符串等类型。PHP 的变量是使用结构体 zval 表示的

PHP 5.* zval 和 Zend_value 结构

struct _zval_struct { // 结构体    zvalue_value value;    Zend_uint refcount__gc;    Zend_uchar type;    Zend_uchar is_ref__gc;}typedef union _zvalue_value { // 联合体    long lval;    double dval;    struct {        char *val;        int len;    } str; // 字符串    Hashtable *ht; // 数组    Zend_object_value obj; // 对象    Zend_ast *ast;} zvalue_value;

PHP 7.0 zval 和 Zend_value 结构

struct _zval_struct {    union {        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;    } value;    union {        struct {            ZenD_ENDIAN_LOHI_4(                Zend_uchar    type,         /* active type */                Zend_uchar    type_flags,                Zend_uchar    const_flags,                Zend_uchar    reserved)     /* call info for EX(This) */        } v;        uint32_t type_info;    } u1;    union {        uint32_t     var_flags;        uint32_t     next;                 /* hash collision chain */        uint32_t     cache_slot;           /* literal cache slot */        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 */    } u2;};

PHP5 与 PHP7 引用计数的对比

PHP 5.* 变量赋值等 *** 作引用计数如图所示,在倒数第二步,会形成一个循环引用,并且在 unset *** 作之后,会产生垃圾。

PHP 7 的计数放到了具体的 value 中,zval 不存在写时复制(写时分离)。

并且 PHP 7 的有一个专门的 Zend_reference 用来表示引用。

有了以上关于 PHP 变量存储的知识,我们可以理解一下 PHP 是如何做垃圾回收的了。

什么是垃圾

首先,我们需要定义什么是垃圾。

1. refcount 增加的不是

2. refcount 等于0的不是,这个会被直接清除

3. refcount 减少,并且不等于0的才是垃圾

垃圾收集

1. PHP7 要求数据类型是数组和对象,并且 type_flag 是 IS_TYPE_ColLECtable

2. 没有在缓冲区中存在过

3. 没有被标记过

4. 标记为紫色,并且放到缓冲区中

回收算法

论文:https://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf

PHP 5.3 版本以及之后的版本

1. 将垃圾放到一个 root 池中

2. 当满 10000 个节点的时候进行垃圾回收

3. 遍历双向链表中的节点 refcount-1

4. 遍历双向链表将 refcount=0 的节点删除,到free队列中

5. 对 refcount!=0 的 refcount+1

总结

以上是内存溢出为你收集整理的PHP是如何做垃圾回收的(图文)全部内容,希望文章能够帮你解决PHP是如何做垃圾回收的(图文)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

© 版权声明
THE END
喜欢就支持一下吧
点赞69 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容