关于PHP 7引用计数的困惑

12
<?php

$s = "foobar";

$t = $s;

$u = $s;

echo PHP_VERSION . "\n";

debug_zval_dump($s);

xdebug_debug_zval('s');

在 PHP 5.6.16 中运行

php 5 refcount

在PHP 7.0.2中运行

php 7 refcount

我认为结果(PHP 7)应该是:

string(6) "foobar" refcount(4)
s: (refcount=3, is_ref=0)="foobar"

我想知道有什么不同之处?需要一些解释。非常感谢。
------ 更新 ------
Nikita Popov的《PHP 7-内部有什么变化?》(P41)

http://www.slideshare.net/nikita_ppv/php-7-what-changed-internally

slideshare


http://php.net/manual/en/features.gc.refcounting-basics.php - devpro
1
@devpro 为什么引用计数为0? - Lynn
引用计数可以为0或1,它是引用集的一部分。 0和1表示是或不是一部分...无论如何,我不是投票者...我建议向投票者推荐改进。 - devpro
实际上,你可以问为什么引用计数为0...这是个合理的问题...兄弟.. - devpro
2
https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html - Steve
显示剩余5条评论
1个回答

15
在 PHP 7 中,zval 可以是具有引用计数的,也可以是没有引用计数的。zval 结构中有一个标志位来确定这一点。
有一些类型永远不会被引用计数,这些类型包括 null、bool、int 和 double。
还有一些类型总是被引用计数的,它们是对象、资源和引用。
然后还有一些类型,它们有时候会被引用计数。这些类型包括字符串和数组。
对于字符串来说,未被引用计数的变体被称为“内部字符串”。如果您正在使用 NTS(非线程安全)的 PHP 7 构建,通常情况下您的代码中所有的字符串字面量都将被合并成内部字符串。这些内部字符串是去重的(即只有一个特定内容的内部字符串),并且在请求的完整持续时间内都保证存在,因此无需为它们使用引用计数。如果使用了 opcache,则这些字符串将存储在共享内存中,在这种情况下,您无法为它们使用引用计数(因为我们的引用计数机制是非原子的)。内部字符串的虚引用计数为1,这就是您在此处看到的内容。
对于数组来说,未被引用计数的变体被称为“不可变数组”。如果您使用了 opcache,则代码中的常量数组字面量将被转换为不可变数组。同样,这些数组位于共享内存中,因此不能使用引用计数。不可变数组的虚引用计数为2,因为它允许我们优化某些分离路径。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接