php 内存分配和管理

[size=large][align=center]zend解析 php 变量的赋值操作[/align][/size]

[size=medium][align=left]前提。我们需要知道php 的内核zend:
Zend整体用纯c实现,是php的内核部分,它将php代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如hashtable、oo)、内存分配及管理、提供了相应的api方法供外部调用,是一切的核心,所有的外围功能均围绕zend实现。
那么我们说到的内存分配和管理,自然是由zend 来完成的,那么zend 是如何针对变量进行内存分配和管理的呢?
[/align][/size]


zend 中对变量的声明:

struct _zval_struct {
    zvalue_value value; /* 变量的值 */
    zend_uint refcount__gc; /*符号表中 变量名的个数*/
    zend_uchar type;    /* 变量当前的数据类型 */
    zend_uchar is_ref__gc; /**/
};
typedef struct _zval_struct zval;



[color=red][size=medium]一: 变量的简单赋值操作。[/size][/color]


看一段php 代码

<?php
$a = "xxxx";
$b = $a;
$b = "yyy";// 或者 unset($a);
?>


[size=medium]在这里,第一步 $a="xxxx";
[color=red]$a的值 字符串“xxxx” 保存在毫不相关的结构体zval 中的 value 项。 而变量的名称$a 则是通过 zend 的方法 zend_hash_add把它添加到符号表里。即:也就是将zval的指针的变量存放在了符号表中。这样才能用$a 访问到 “xxxx”。 这个时候,只有$a 指向 zval 所以 refcount=1.
[/color]
下面是 一个zend 的源码 对赋值操作的解释:[/size]


{
zval *fooval;
MAKE_STD_ZVAL(fooval);
ZVAL_STRING(fooval, "xxxx", 1);
ZEND_SET_SYMBOL( EG(active_symbol_table) , "a" , fooval);
}

[size=medium]首先,我们声明一个zval指针,并申请一块内存。然后通过ZVAL_STRING宏将值设置为‘xxxx’,最后一行的作用就是将这个zval加入到当前的符号表里去,并将其label定义成a,这样用户就可以在代码里通过$a来使用它了。

第二步 $b = $a ;
[color=red]将$a赋值给$b ,zend 方法 zend_hash_add把变量名称 zval指针的变量$b 添加到符号表里。 通过结构体zval 达到共享。 从而节省了内存。也就是:符号表中b也是存放的zval指针变量。 符号表中 a b 对应同一个zval指针的地址 所以refcount=2[/color]


假如说 第三步操作 是 unset($a);
释放$a的值 zval 中的value。 那么是不是$b 的值也就不存在了?

其实不是这样的,在结构体zval 中有一个属性 refcount . 它会处理掉这样的问题。

refcount : 当变量被创建并且赋值的时候,在符号表中变量 a 通过zval指针 和内存中zval结构体建立联系,这个时候refcount=1 ,当$b=$a.的时候,也就是变量名称b 也是通过zval指针 和内存中zval结构体建立联系,这个时候 refcount=2.,所以unset只需把这个zval的refcount减去1就行了![color=red]结果就是 只有 符号表中的b 通过zval类型的指针 和 zval(存放字符串的zval结构体)建立联系 。[/color]

假如说 第三步操作是 $b="yyy";
结果肯定是$b 和 $a 各有一个值。[color=blue]当执行赋值的时候,也就是要改变变量$b的值的时候,他们就不能共享zval 了。zend 会判断zval 中的refcount 是否大于1,大于1的话。 这个时候zend 会复制一个的zval 来 存储b , 并且重新定义符号表中的b ,新建一个新的zval指针 指向新的zval[/color]


以上是我对变量 在php内存分配的理解。哪里不对 希望大家指出

未完待续。

二:zend 引用变量的赋值


[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值