关于 PHP 7 refcount 的困惑
Confusion about PHP 7 refcount
<?php
$s = "foobar";
$t = $s;
$u = $s;
echo PHP_VERSION . "\n";
debug_zval_dump($s);
xdebug_debug_zval('s');
运行 在 PHP 5.6.16
运行 在 PHP 7.0.2
我认为结果(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
在PHP7中,zval可以是引用计数也可以不是。 zval 结构中有一个标志决定了这一点。
有些类型永远不会被重新计算。这些类型是 null、bool、int 和 double。
还有其他类型总是被重新计算。这些是对象、资源和引用。
然后是类型,有时 重新计数。这些是字符串和数组。
对于字符串,not-refcounted 变体称为 "interned string"。如果您使用的是 NTS(不是 thread-safe)PHP 7 版本(通常是这样),那么您代码中的所有字符串文字都将被保留。这些驻留字符串是重复数据删除的(即只有一个带有特定内容的驻留字符串)并且保证在请求的整个持续时间内存在,因此不需要对它们使用引用计数。如果您使用 opcache,这些字符串将存在于共享内存中,在这种情况下您不能 对它们使用引用计数(因为我们的引用计数机制是 non-atomic)。实习字符串的虚拟引用计数为 1,这就是您在此处看到的内容。
对于数组,not-refcounted 变体称为 "immutable array"。如果您使用 opcache,那么您代码中的常量数组文字将被转换为不可变数组。同样,它们位于共享内存中,因此不能使用引用计数。不可变数组的虚拟引用计数为 2,因为它允许我们优化某些分离路径。
<?php
$s = "foobar";
$t = $s;
$u = $s;
echo PHP_VERSION . "\n";
debug_zval_dump($s);
xdebug_debug_zval('s');
运行 在 PHP 5.6.16
运行 在 PHP 7.0.2
我认为结果(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
在PHP7中,zval可以是引用计数也可以不是。 zval 结构中有一个标志决定了这一点。
有些类型永远不会被重新计算。这些类型是 null、bool、int 和 double。
还有其他类型总是被重新计算。这些是对象、资源和引用。
然后是类型,有时 重新计数。这些是字符串和数组。
对于字符串,not-refcounted 变体称为 "interned string"。如果您使用的是 NTS(不是 thread-safe)PHP 7 版本(通常是这样),那么您代码中的所有字符串文字都将被保留。这些驻留字符串是重复数据删除的(即只有一个带有特定内容的驻留字符串)并且保证在请求的整个持续时间内存在,因此不需要对它们使用引用计数。如果您使用 opcache,这些字符串将存在于共享内存中,在这种情况下您不能 对它们使用引用计数(因为我们的引用计数机制是 non-atomic)。实习字符串的虚拟引用计数为 1,这就是您在此处看到的内容。
对于数组,not-refcounted 变体称为 "immutable array"。如果您使用 opcache,那么您代码中的常量数组文字将被转换为不可变数组。同样,它们位于共享内存中,因此不能使用引用计数。不可变数组的虚拟引用计数为 2,因为它允许我们优化某些分离路径。