php - 关于 PHP 7 refcount 的困惑

标签 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 的 - PHP 7 – 内部发生了什么变化? (P41)

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

slideshare

最佳答案

在 PHP 7 中,zval 可以是引用计数也可以不是。 zval 结构中有一个标志决定了这一点。

有些类型永远不会重新计算。这些类型是 null、bool、int 和 double。

还有其他类型总是被重新计算。这些是对象、资源和引用。

然后是一些类型,有时 refcounted。这些是字符串和数组。

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

对于数组,未引用计数的变体称为“不可变数组”。如果您使用 opcache,那么您代码中的常量数组文字将被转换为不可变数组。同样,它们位于共享内存中,因此不能使用引用计数。不可变数组的虚拟引用计数为 2,因为它允许我们优化某些分离路径。

关于php - 关于 PHP 7 refcount 的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34764119/

相关文章:

php - 使用 DOMDocument 和 DOMXPath 正确删除 PHP 中的子元素

javascript - 如何从 jQuery 数据库中获取星级数据?

php - 可以从 Youtube 视频中捕获静止帧吗?

php - 从 php 扩展调用对象构造函数 (__construct)

php - 构建 PHP 扩展并使用 call_user_function

php - 以下哪一个 PHP 数组结构会使用更少的内存?

php - 当我们在循环中没有修改数组时,为什么 foreach 会复制数组?

php - 多个 mysql 表与 php 连接?

php - 用于编码 UTF8 的 Postgresql PHP 无效字节序列

php - 如何将 zval 转换为 vector 以用于 php 扩展?