PHP7内核学习笔记 - zval中的知识点

  • PHP5中的zval结构
struct _zval_struct {
    union {
        long lval;
        double dval;
        struct {
            char *val;
            int len;
        } str;
        HashTable *ht;
        zend_object_value obj;
        zend_ast *ast;
    } value;
    zend_uint refcount__gc;
    zend_uchar type;
    zend_uchar is_ref__gc;
};
  • PHP7中的zval结构
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;
};
  • GC机制:仅支持数组和对象(IS_TYPE_COLLECTABLE)
  • 第一步将紫色标记为灰色,并将计数引用减1
  • 第二步仅操作灰色。若计数引用大于0,则说明非垃圾,标为黑色,并将计数引用加1(第一步中做了减1操作)。若计数引用等于0,则说明是垃圾,标为白色。
  • 移除黑色(非垃圾,不需要处理),保留白色(垃圾,需要回收)。将白色的计数引用加1,然后将处理后的roots链表移动到待释放列表(to_free
  • 释放to_free
  • 计数引用和写时复制
  • 计数引用说白了就是用来标记一个变量所指向的值被使用了多少次
  • 简单类型的变量(true/false/double/long/null)不需要引用计数
  • 临时字符串会用到引用计数。但如果变量是字符常量,则不会用到
  • 对象、资源和引用在赋值时一定会用到引用计数
  • 普通数组在赋值时也会用到引用计数,但是变量是IS_ARRAY_IMMUTABLE时,赋值不使用引用计数
  • 一个zval是否支持引用计数是通过zval.u1.type_flag来标识的。当type_flag的第三位被标记为1(IS_TYPE_REFCOUNTED标识),则代表可以引用计数。
  • 写时复制这种机制是用于节省资源的。当变量只是复制后用来展示而不做改变,那么新老变量指向的都是同一个值。当新老变量有任何一方作出变动,都会触发写时复制的机制,使得两者脱离,分别指向自己私有的值了(这时候不再共用)。
  • 变量的作用域
  • 局部变量
  • 全局变量
  • 对于复制的支持(IS_TYPE_COPYABLE)
  • 需要查找IS_TYPE_COPYABLE,除了对象和资源,其他都支持。意味着对象和资源在赋值操作之后,新的变量和老的变量指向的是同一个对象(资源)。而其他的变量类型则支持赋值(整型和浮点型会直接生成一份新的,不需要计数引用和写时复制)。
  • 只有stringarray支持复制
  • 对于引用计数的支持(IS_TYPE_REFCOUNTED)
  • 支持技术引用的类型有:stringarrayobjectresourcerefrence
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值