php7引用计数,PHP7 引用计数 读书笔记

每个php变量存在一个加"zval"的变量容器中。一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息。

1.is_ref :是一个bool值,用来标识这个变量是否属于引用集合。通过这个字节,php引擎才能把普通变量和引用变量区分开来,由于php允许用户通过&来自定义引用,zval变量容器中还有一个内部引用计数机制,来优化内存使用。

2.refcount,用来表示指向这个zval变量容器的变量(也称为符号symbol)个数。所有的符号存在一个符号表中,其中每个符号都有作用域,那些主脚本和每个函数或者方法也都有作用域。

接下来我们通过几个例子来帮助大家理解。(以下代码是在 Linux+php7.1环境下)

1.生成一个新的zval 容器

$a = ‘new string‘;

xdebug_debug_zval(‘a‘);

输出结果如下:

60cbc19b0c1e3f8421a0187551e5a675.png

从结果可以看出 refount = 0,is_ref=0 那怎么理解这个输出结果呢?

(1)is_ref = 0 信息很容易理解,$a 不是一个引用变量自然就是0

(2)refount 的值怎么也是0,因为我们知道在php7中对于简单的数据类型,比如整型,字符串,浮点型等简单类型的值是直接存储在zval结构里面。

如果把变量a赋值给多个变量会怎样?

$a = "new string";

$c = $b = $a;

xdebug_debug_zval( ‘a‘ );

输出结果如下:

2197a88ccd2311cee25999732d17d4cc.png

发现refcount的值还是0,三个变量共用1个zval结构,没有存符号表。下面我们再给看下变量被引用后的情况:

$a = "new string";

$b = &$a;

$c = &$b ;

xdebug_debug_zval( ‘a‘ );

xdebug_debug_zval( ‘b‘ );

xdebug_debug_zval( ‘c‘ );

输出结果如下:

4153cfd25dd032d14d54e5eed063615e.png

我们发现三个变量的refount和is_ref都相同,那我们来解释下:

1.当变量被引用后,原来的zval结构会发生变化,php 会新增一个_zend_reference结构,这个结构会根据值得类型不同而不同。

struct _zend_reference {

zend_refcounted_h gc;

zval val;

}

我们来看下php的具体操作:

(1)php会申请一个zend_reference结构

(2)将zval_reference.value 指向原来的 zval_struct.value

(3)zval_struct.value 的数据类型修改为zend_refrence

(4)将zval_struct.value 指向刚刚申请并初始化的 zend_reference

(5)为新变量申请zval_struct 结构,将他的value 指向刚刚创建的zend_reference

原文:https://www.cnblogs.com/shuzhen2020/p/12196216.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值