说明: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'