PHP的引用计数和写时复制

说明:PHP的引用计数和写时复制

一:变量引用和计数

$a = 'hello world';

上面这个语句在php引擎中是怎么表示的呢? a:refcount=1; is_ref=0;

$b = $a;

$a给$b赋值后, zval中的refcount和is_ref有怎么变化呢? a:refcount=2; is_ref=0; refcount变成 2 了

$a = 'hello world'; 
$b = &$a;

上面的代码zval中引用和计数又会发生什么变化呢? a:refcount=2; is_ref=1; 这时候 is_ref就变成1了

二:变量的分离 conpy on write

$a = 'hello world';
$b = $a;
$b = 'new string';
echo $a;
echo $b;

输出结构是: hello world new string
看上面$a 赋值 给$b了, 应该是指向了同一个zval, 那为什么输出值又是不同的呢? 这里就用到了一种技术 copy on write 写时复制,过程如下

$a = 'hello world '; // a:(refcount=1; is_ref=0) = 'hello world'
$b = $a;            // a,b :(refcount=2; is_ref=0) = 'hello world'; 
$b = 'new string';  // a:(refcount=1; is_ref=0) = 'hello world' b:(refcount=1; is_ref=0; a:is_ref) = 'new string', 发生分离操作,从新生成一个zval存储b的值,并且refcount=1

refcount=2的时候,如果引用就发生变量的分离

$a = 'hello world';  //a:(refcount=1; is_ref=0) = 'hello world'
$c = $a;             //a,c:(refcount=2; is_ref=0) = 'hello world'
$b = &$a;            //a,b:(refcount=2, is_ref=1) = 'hello world',  c:(refcount=1, is_ref=0) = 'hello world' (发生分离)
$b = 'new string';    //a,b:(refcount=2, is_ref=1) = 'hello world', c:(refcount=1, is_ref=0) = 'new string'

参考-都是源自这里,作者讲解的很清晰

http://blog.csdn.net/phpkernel/article/details/5732784