php refcount,php zval中的refcount问题详解

今天群里面的一位小伙伴问我关于PHP变量中refcount的问题,当时回答给他了,发现自己没注意到一个细节,记录下来。

什么是refcount

“zval结构体中有四个字段,其含义分别为:

属性名 含义 默认值

refcount__gc 表示引用计数 1

is_ref__gc 表示是否为引用 0

value 存储变量的值

type 变量具体的类型”

摘录来自: Reeze Xia. “TIPI: 深入理解PHP内核”。

refcount是php用来对zval变量引用次数技术的一个变量值。

它是一个计数器,用来保存有多少符号表有多少符号指向该zval。在变量生成时,其refcount=1,赋值操作$a = $b会令zval的refcount加1,zval的refcount如果减少到0,会释放该zval所占的内存空间。

问题是什么?

小伙伴原问题是为什么下面的计数会是3.

52e4410ef0f9f1f8bd98063b0716f53e.png

因为照上面的说法zval $a在被赋值为100的时候应该为1,$b = $a 的时候应该再加1,那么debug_zval_dump()函数照理来说应该显示2,而不应该显示3。

当时我的回答是,初始化的时候值为1,赋值的时候再加1,赋值给$b的时候再加1,所以是3。

但是后来他提出,使用xdebug_zval_dump()出来refcount的值是2。

那么,我之前的答案就是错的,惭愧,学艺不精。

于是我找了一些资料来研究两个函数之间处理的差异。

下面就是差异的原因。

PHP's debug_zval_dump takes a variable as argument for analysis and is thus also bound to the same splitting rules as outlined earlier. This means that's not really well suited for dumping a zval's internal structure as it would always modify the zval. Besides adding 1 to the refcount field, it could also force a split resulting in unexpected output:

shows:

long(42) refcount(2)

Xdebug has a similar function to display a zval's internal data: xdebug_debug_zval. This function does requires not a variable to be passed as its argument, but instead requires a variable name to be passed in. With this, the manipulation of the zval is avoided and the proper values are shown:

which shows:

a: (refcount=1, is_ref=0)=42

所以单纯的$a的refcount=0,赋值操作会+1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值