您现在的位置是:首页 > 程序 > php网站首页php
PHP底层原理分析(二):写时复制和强制分裂
学习需要知其然而知其所以然,PHP底层相关就是这类知识,从上文中知道声明一个变量,将会产生一个结构体,那么在传值赋值和引用赋值时, 结构体是如何变化的呢?
从上文(http://blog.yzmcms.com/html/php/173.html) 中知道声明一个变量,将会产生一个结构体,那么在传值赋值和引用赋值时, 结构体是如何变化的呢?
一、变量的传值赋值:
以: $a = 3 ; $b = $a为例,此时并没有再次产生结构体,而是2个变量共用1个结构体,refcount__gc 值为2。
$a = 3
此时的结构体:
{ value:3 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$b = $a;
此时$a和$b共用一个结构体:
{ value:3 type:IS_LONG refcount__gc:2 is_ref__gc:0 }
思考: a, b指向同一个结构体, 那么,修改a,或b ,对方会不会受干扰?
答: 不会,
因为两者,有一方修改时,将会造成结构体的分裂。
$b = 5; //此时修改变量的值
结构体如下:
$a的结构体是:
{ value:3 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$b的结构体是:
{ value:5 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
结构体一开始共用,到某一方要修改值时,才分裂。这种特点称为Copy-on-Write,也就是写时复制。
二、变量的引用赋值:
当引用赋值时, 双方共用一个结构体(is_ref__gc=1)
$a = 1;
此时的结构体:
{ value:1 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$b = &$a;
此时$a和$b共用一个结构体:
{ value:1 type:IS_LONG refcount__gc:2 is_ref__gc:1 }
is_ref__gc:1表示引用赋值,此时,如果修改$a和$b任意一个值,结构体不会分裂,$a和$b两个值也将都会修改;
三、强制分裂:
那么现在有这样一个代码:
$a = 3; $b = $a; $c = &$a; $c = 5; echo $a.$b.$c; //535
为什么会是这样的结果呢,这跟上面我们讲的结构体不一样呢?
原因就是此时发生了强制分裂!
当is_ref__gc[引用属性]从0->1,如果refcount__gc>1,那么就会发生强制分裂。
这个就是强制分裂。原本已经经过传值赋值的变量,再次引用赋值出去。被传值赋值的变量就会被分裂出一个结构体,简单可以理解为:在引用变量主动赋值前,该变量传值赋值过,就会发生强制分裂。
上述代码中:
$b强制分裂出一个结构体:
{ value:3 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$a个$c共用一个结构体:
{ value:5 type:IS_LONG refcount__gc:2 is_ref__gc:1 }
注意:在数组中慎用引用赋值,例如:
$arr = array(0,1,2,3); $x = &$arr[1]; $tem = $arr; $arr[1] = 999; echo $tem[1]; //结果为 999
相关文章
文章评论 (0)
- 这篇文章还没有收到评论,赶紧来抢沙发吧~