php底层学习-从底层分析引用

本文从燕十八老师视频学习中总结

给变量赋值的时候发生了什么?

例如:
$a = 1;
$b = $a;

在第一次赋值的时候,产生了一个结构体,并在symbol_table中记录了变量名和结构体的内存地址
{
{zvalue:1length:1}
type:is_LONG
refcount_gc:1
is_ref_gc:0
}

其中值是记录在内存中,与此同时在symbol_table中记录了变量名和结构体的地址
在第二次$b=$a赋值的过程中发生了什么呢?

这并没有产生新的结构体,而是第一次产生的结构体发生一些改变
{
{zvalue:1,length:1}
type:IS_LONG
refcoungt_gc:2,
is_ref_gc:1
}

这里的refcount_gc增加了一次,与此同时在symbol_table中新增了变量名b和上面结构体地址的记录,两者的结构体是同一个
此时a,b使用的是统一个结构体,指向的是同一块内存单元
总结:在 a=1; a = 1 ; b=2时,并没有产生新的结构体,而是两个变量公用1个结构体

a,b共用一个结构体,若修改a或b,另一个又发生了什么?

例如:当$b = 6;重新赋值时
此时结构体发生了改变,b产生一个新的结构体

{
{zvalue:6
length:1}
type:IS_LONG
refcount_gc:1
is_ref_gc:0
}

同时symbol_table中修改了b的内存地址,改为新的结构体地址
第一个结构体也发生一些变化

{
{
zvalue:1
length:1
}
type:IS_LONG
ref_counf_gc:1 //此时减1
is_ref_gc:0
}

这种称为COW(copy on write) , 只有在重新赋值时会重新存储数据,否则多个变量使用同一数据
结构体刚开始共用,某一方值要修改时才进行分裂
大部分语言常用的一种方式

当引用传值时,结构体会发生什么变化呢?

例:
$a = 1;
$b = &$a;
$b = 3;
echo $a;
这次我们重新来分析

当给a赋值1时,会产生一个结构体,如下
{
{
zvalue:1
length:1
}
type:IS_LONG
refcount_gc:1
is_ref_gc:0
}

产生一个结构体,同时symbol_table记录了变量名a和结构体的地址
当变量b对变量a进行引用时,并不会产生新的结构体,知识结构体发生了一些变化,变化如图

{
{
zvalue:1,
length:1
}
type:IS_LONG
refcount_gc:2 // 这时refcount增加1
is_ref_gc:1 //注意此时的变化,结构体的这个字段标识了是否为引用
}
此时symbol_table中记录了变量b和结构体的地址,此时和a记录的地址为同一个地址

当我们对b进行修改时,可以看下结构体的变化
例 $a = 6;

此时结构体并没有分裂,因为a,b对结构体都有引用关系,共用一个结构体
{
{
zvalue:5 // 此时这个结构体的值发生了变化
length:1
}
type:IS_LONG
ref_count_gc:2
is_ref-gc:1
}

因为a,b都是使用的这个结构体,所以当一个产生变化后,另外一个变量也会产生变化
此时$a 的值也是5
总结:引用时,is_ref_gc值为1,说明这个结构体和变量是引用关系,当另一个值改变时,结构体并不分裂,所以所有指向这个结构体的变量的值都会发生变化

引用传值中结构体的强制分裂

例:
$a = 3;
$b = $a;
$c = &$a;
$c = 6;
此时a,b,c的值分别 6,3,6

当a赋值时,生成一个结构体
{
{
zvalue:3,
length:1
}
type:IS_LONG
refcount_gc:1
is_ref_gc:0
}

此时在symbol_table生成变量a的名和结构体对应的存储位置
当把a值赋值给b时
此时的结构体发生下面变化.refcount_gc加一,同时symbol_table中记录了b的名,并且记录结构体的存储位置,和a记录的是同一个值

{
{
zvalue:3,
length:1
}
type:IS_LONG
refcount_gc:2
is_ref_gc:0
}

当变量c对变量a进行引用时,结构体会产生下面的变化,此时出现了强制复制的概念

{
{
zvalue:3
length:1
}
type:IS_LONG
refcount_gc:2
is_ref_gc:1
}

此时变量c和a引用的同一个结构体,任用一个值发生改变另一个值也会发生改变
当is_ref_gc改变时,会对refcount_gc进行判断,当refcount_gc>1时,会对其他共用这个结构体的所有变量进行强制复制,因为之前b和a共用,所以此时b会产生独自的结构体

{
{
zvalue:3,
length:1
}
type:IS_LONG
refcount_gc:1
is_ref_gc:0
}

并且symbol_table表中的b对应的地址会发生相应的改变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值