注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

记录~~~

Stay Hungry. Stay Foolish.

 
 
 

日志

 
 

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

2014-06-06 09:05:59|  分类: PHP |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
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容器。
  评论这张
 
阅读(149)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017