设为首页 收藏本站
查看: 2125|回复: 0

[经验分享] php 内存分配和管理

[复制链接]

尚未签到

发表于 2017-3-26 10:37:34 | 显示全部楼层 |阅读模式
zend解析 php 变量的赋值操作

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



zend 中对变量的声明:

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


一: 变量的简单赋值操作。

看一段php 代码

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


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

下面是 一个zend 的源码 对赋值操作的解释:

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

首先,我们声明一个zval指针,并申请一块内存。然后通过ZVAL_STRING宏将值设置为‘xxxx’,最后一行的作用就是将这个zval加入到当前的符号表里去,并将其label定义成a,这样用户就可以在代码里通过$a来使用它了。
第二步  $b = $a ;
     将$a赋值给$b ,zend 方法 zend_hash_add把变量名称 zval指针的变量$b 添加到符号表里。  通过结构体zval 达到共享。 从而节省了内存。也就是:符号表中b也是存放的zval指针变量。   符号表中 a  b 对应同一个zval指针的地址   所以refcount=2

假如说 第三步操作 是   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就行了!结果就是 只有 符号表中的b 通过zval类型的指针 和 zval(存放字符串的zval结构体)建立联系 。
假如说 第三步操作是 $b="yyy";
结果肯定是$b 和 $a 各有一个值。当执行赋值的时候,也就是要改变变量$b的值的时候,他们就不能共享zval 了。zend 会判断zval 中的refcount 是否大于1,大于1的话。 这个时候zend 会复制一个的zval 来 存储b  , 并且重新定义符号表中的b ,新建一个新的zval指针 指向新的zval

以上是我对变量 在php内存分配的理解。哪里不对  希望大家指出
未完待续。
二:zend 引用变量的赋值

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-355528-1-1.html 上篇帖子: php yii asset资源配置 下篇帖子: 基于php缓存的详解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表