【问题标题】:How two arrays share zval containers in PHP?PHP 中两个数组如何共享 zval 容器?
【发布时间】:2021-06-16 19:36:39
【问题描述】:

我正在研究 PHP 内存管理的基础知识,我发现它非常有趣。不幸的是,内存管理的内部结构似乎根据 PHP 版本发生了变化,因此与解释我们应该期待什么结果的不同资源相比,我并不总是理解 xdebug_debug_zval 返回的结果。没关系,因为我主要对全局感兴趣,但它阻止我运行测试来测试我的知识。

我想解决的问题很简单:

$a=array(1,2);
$b=$a;
$b[0]='foo';
$b[]='bar';

做作之后$b=$aab符号都指向同一个zval(refcount=2)。到目前为止,一切都很好。但是在$b[0]='foo'; 指令之后,ab 是否仍然指向它们共同的 zval?修改后如何处理?

同样的想法,在$b[]='bar';之后做ab仍然指向同一个zval并创建一个新节点(即创建一个新的zval来存储'bar'指向的3,添加到$b) 的密钥?

运行xdebug_debug_zval('a')xdebug_debug_zval('b') 分别给了我

a: (refcount=2, is_ref=0)=array (0 => (refcount=0, is_ref=0)=1, 1 => (refcount=0, is_ref=0)=2, 2 => (refcount=0, is_ref=0)=3)
b: (refcount=1, is_ref=0)=array (0 => (interned, is_ref=0)='foo', 1 => (refcount=0, is_ref=0)=2, 2 => (refcount=0, is_ref=0)=3, 3 => (interned, is_ref=0)='bar')

我不确定如何解释它以及是否回答了我的问题。我可以看到ab 确实指向同一个zval 数组,仅此而已。如何处理差异?

所以我的问题是 PHP 是否像树一样处理内存,通过共享符号 ab 指向的节点(zval)并通过添加节点(zval)来适应它们之间的差异?

非常感谢您的任何回答,对不起,我的问题的标题不是很好

【问题讨论】:

    标签: php memory


    【解决方案1】:

    我认为这个博客可以提供帮助。 https://blog.larapulse.com/php/variables-under-the-hood

    现在,如果您更改这些变量之一的值,PHP 看到 refcount 大于 1,将复制此 zval,在那里进行更改,您的变量将指向新的 zval。

    【讨论】:

    • 感谢您的资源。总结一下,我从你的链接和这个链接npopov.com/2015/05/05/… 中了解到的,它侧重于 zval 的 PHP7 实现:一旦发生修改,数组就会被复制。并且没有共享 zval。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    相关资源
    最近更新 更多