理解php内核的 引用计数器与写时复制

zval结构中有以下两个成员变量用于引用计数器:
is_ref:BOOL值,标识变量是否是引用集合
refcount:计算指向引用集合的变量个数


写时复制:就是当变量的值改变时才进行内存的复制。

<?php

$a = "this a test ";

xdebug_debug_zval('a');

$b = $a;

xdebug_debug_zval('a');

$a = "changed the test value";

xdebug_debug_zval('a');

执行结果:

a:

(refcount=1, is_ref=0),string 'this a test ' (length=12)
a: 
(refcount=2, is_ref=0),string 'this a test ' (length=12)
a: 
(refcount=1, is_ref=0),string 'changed the test value' (length=22)
当$a的值赋给变量$b时,变量$a的refcount增加1,所以这时候变量$a跟变量$b是指向同一内存块的;
改变$a的值时,发现refcount的值变回1,所有这时候变量$a和$b 指向不同的内存块,这就是写时复制。就是两个指向同一内存块的变量,当其中一个变量的发生变化,才会另外创建一个内存块去保存新的值。

写时复制也是一种引用,只不过这种引用会受到变量值的改变而破坏罢了。

显式引用情况:

<?php

$a = 1;

xdebug_debug_zval('a');

$b = & $a;

xdebug_debug_zval('a');

$b += 5;

xdebug_debug_zval('a');

执行结果:

a:

(refcount=1, is_ref=0),int 1
a: 
(refcount=2, is_ref=1),int 1
a: 
(refcount=2, is_ref=1),int 6
is_ref字段等于1,表示此变量被引用。refcount也相应+1

在PHP内核中通过以下代码判断是否复制变量:

if ((*varval->is_ref || (*varval)->refcount<2)) {

return *varval;

}

当变量被引用,或者引用计数器小于2时会直接返回变量的指针(直接返回变量的实体,而不复制变量的值)。当修改一个被引用变量的值时,所有引用他的变量其值也会被修改,因为他们指向同一个zval容器。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值