关于PHP 7 refcount的困惑

时间:2016-01-13 10:23:31

标签: php php-internals

<?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&#39; PHP 7 - 内部发生了什么变化? (P41)

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

slideshare

1 个答案:

答案 0 :(得分:13)

在PHP 7中,zval可以引用计数与否。 zval结构中有一个标志确定了这一点。

有些类型从未被重新计算过。这些类型为null,bool,int和double。

还有其他类型总是被重新计算。这些是对象,资源和参考。

然后有类型,有时已重新计算。那些是字符串和数组。

对于字符串,not-refcounted变体称为&#34; interned string&#34;。如果您正在使用NTS(非线程安全)PHP 7构建(通常是这样),则代码中的所有字符串文字都将被实现。这些实习字符串经过重复数据删除(即只有一个具有特定内容的实习字符串)并且保证在请求的整个持续时间内存在,因此不需要对它们使用引用计数。如果使用opcache,这些字符串将存在于共享内存中,在这种情况下,不能使用引用计数(因为我们的引用计数机制是非原子的)。实习字符串的虚拟引用计数为1,这是您在此处看到的内容。

对于数组,not-refcounted变体称为&#34;不可变数组&#34;。如果使用opcache,则代码中的常量数组文字将转换为不可变数组。再次,这些生活在共享内存中,因此不得使用引用计数。不可变数组的伪引用计数为2,因为它允许我们优化某些分离路径。