• php 变量的分配和销毁


    引用计数

    引用计数是指在value中增加一个字段refcount记录指向当前value的数量,变量复制、函数传参时并不直接硬拷贝一份value数据,而是将refcount++,变量销毁时将refcount--,等到refcount减为0时表示已经没有变量引用这个value,将它销毁即可。

    存储结构如下:

     1 typedef struct _zend_refcounted_h {
     2     uint32_t         refcount;            /* reference counter 32-bit */
     3     union {
     4         struct {
     5             ZEND_ENDIAN_LOHI_3(
     6                 zend_uchar    type,
     7                 zend_uchar    flags,    /* used for strings & objects */
     8                 uint16_t      gc_info)  /* keeps GC root number (or 0) and color */
     9         } v;
    10         uint32_t type_info;
    11     } u;
    12 } zend_refcounted_h;

    引用计数的信息位于给具体value结构的gc中,例如在字符串变量中:

    1 typedef struct _zend_string     zend_string;
    2 struct _zend_string {
    3     zend_refcounted_h gc;
    4     zend_ulong        h;                /* hash value */
    5     size_t            len;
    6     char              val[1];
    7 };

    写时复制

    引用计数,多个变量可能指向同一个value,然后通过refcount统计引用数,这时候如果其中一个变量试图更改value的内容则会重新拷贝一份value修改,同时断开旧的指向,写时复制的机制在计算机系统中有非常广的应用,它只有在必要的时候(写)才会发生硬拷贝,可以很好的提高效率

    不是所有类型都可以copy的,比如对象、资源,实时上只有string、array两种支持,与引用计数相同,也是通过zval.u1.type_flag标识value是否可复制的

    3 变量回收

    PHP变量的回收主要有两种:主动销毁、自动销毁。动销毁指的就是 unset。自动销毁就是PHP的自动管理机制,在return时减掉局部变量的refcount,即使没有显式的return,PHP也会自动给加上这个操作,另外一个就是写时复制时会断开原来value的指向,这时候也会检查断开后旧value的refcount。

    垃圾回收

    PHP变量的回收是根据refcount实现的,当unset、return时会将变量的引用计数减掉,如果refcount减到0则直接释放value,这是变量的简单gc过程

    但是实际过程中出现gc无法回收导致内存泄漏的bug,先看下一个例子:

    1 $a = [1];
    2 $a[] = &$a;
    3 unset($a);

    可以看到,unset($a)之后由于数组中有子元素指向$a,所以refcount > 0,无法通过简单的gc机制回收,这种变量就是垃圾,垃圾回收器要处理的就是这种情况,目前垃圾只会出现在array、object两种类型中,所以只会针对这两种情况作特殊处理:当销毁一个变量时,如果发现减掉refcount后仍然大于0,且类型是IS_ARRAY、IS_OBJECT则将此value放入gc可能垃圾双向链表中,等这个链表达到一定数量后启动检查程序将所有变量检查一遍,如果确定是垃圾则销毁释放。

    for remember
  • 相关阅读:
    Linux下安装软件遇见的问题汇总
    使用AlarmManager定期执行工作
    android打开文件、保存对话框、创建新文件夹对话框(转载)
    一些算法的整理
    安卓adb调试命令常见的问题
    java下的串口通信-RXTX
    Unity 协程运行时的监控和优化
    Unity3D 协程的介绍和使用
    游戏服务器:到底使用UDP还是TCP
    Unity 可重复随机数
  • 原文地址:https://www.cnblogs.com/dearmrli/p/8576078.html
Copyright © 2020-2023  润新知