今天群里面的一位小伙伴问我关于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.
因为照上面的说法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:
$a = 42;
debug_zval_dump($a);
?>
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:
$a = 42;
xdebug_debug_zval('a');
?>
which shows:
a: (refcount=1, is_ref=0)=42
所以单纯的$a的refcount=0,赋值操作会+1
敢达决战官方正版 安卓版v6.7.9
下载敢达决战 安卓版v6.7.9
下载像素火影骨架佐助 (Perseverance Fire Shadow)手机版v1.16
下载要塞英雄 安卓版v33.20.0-39082670-Android
下载梦想城镇vivo最新版本 安卓版v12.0.1
梦想城镇vivo版是这款卡通风模拟经营类手游的渠道服版本,玩
怦然心动的瞬间 安卓版v1.0
怦然心动的瞬间是一款真人向的恋爱互动游戏,在游戏中玩家将扮演
曼尼汉堡店游戏 安卓版v1.0.3
曼尼汉堡店是一款非常好玩的精品恐怖类型冒险游戏,在这款游戏中
现代总统模拟器去广告版 安卓版v1.0.46
现代总统模拟器是一款休闲养成类游戏,可能对于不少的玩家来说都
现代总统模拟器付费完整版 安卓版v1.0.46
现代总统模拟器高级版在商店是需要付费的,相对于普通版本,高级