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 引用变量的赋值
分享到:
相关推荐
因此,理解PHP是如何分配与释放内存的对于创建这类程序极为重要。本文将重点探讨PHP的内存管理问题。 一、 内存在PHP中,填充一个字符串变量相当简单,这只需要一个语句”<?php $str = ‘hello world ‘; ?>”即可...
你可能听说过JAVA、.NET、PHP这些语言有垃圾回收的内存管理机制,但是很少会听到JavaScript也有自己的内存管理机制,JavaScript同样有着类似的垃圾回收功能。本文主要讲述了JavaScript的垃圾回收原理和具体的过程。 ...
一、 内存 在PHP中,填充一...为了创建一个可操纵的字符串,你必须分配一个内存块,并且通过一个函数(例如strdup())来复制其内容。 { char *str; str = strdup(“hello world”); if (!str) { fprintf(stderr,
独创的即时监控,智能分析服务器进程的内存和CPU占用率等信息。 邮件报警 灵活的报警设置,以邮件的方式进行服务异常、设备宕机等告警通知。 单机运维 简单操作即可进行服务器的日常维护与管理,支持通过智能...
③ 支持多FTP用户管理,并为每个FTP用户分配独立的目录或权限。 ④ 支持FTP管理功能,如:FTP密码修改、在线文件管理、FTP用户管理等。 ⑤ 可设置FTP主机是否支持试用以及试用天数。 ⑥ FTP主机升级、续费 3、企业...
垃圾回收机制是一种动态存储分配方案,它会自动释放程序不再需要的已分配的内存块,PHP也在语言层实现了内存的动态管理.内存的动态管理将开发人员从繁琐的内存管理中解救出来
※ 支持多FTP用户管理,并为每个FTP用户分配独立的目录或权限。 ※ 支持FTP管理功能,如:FTP密码修改、FTP状态修改、删除文件、FTP用户管理等。 ※ 可设置FTP主机是否支持试用以及试用天数。 ※ FTP主机升级、续费 ...
③ 支持多FTP用户管理,并为每个FTP用户分配独立的目录或权限。 ④ 支持FTP管理功能,如:FTP密码修改、在线文件管理、FTP用户管理等。 ⑤ 可设置FTP主机是否支持试用以及试用天数。 ⑥ FTP主机升级、...
※ 支持多FTP用户管理,并为每个FTP用户分配独立的目录或权限。 ※ 支持FTP管理功能,如:FTP密码修改、FTP状态修改、删除文件、FTP用户管理等。 ※ 可设置FTP主机是否支持试用以及试用天数。 ※ FTP主机升级、...
事实上,我们发现foo和bar变量因为值相同,完全可以使用同一块内存,这样,内存的使用就节省了一个1,并且,还省去了分配内存和管理内存地址的计算开销。没错,很多涉及到内存管理的系统,都实现了这种相同值共享...
Zend整体用纯c实现,是php的内核部分,它将php代码翻译(词法、语法解析等一系列编译过程)为可执行opcode的处理并实现相应的处理方法、实现了基本的数据结构(如hashtable、oo)、内存分配及管理、提供了相应的api...
14.3.1 管理模式 223 14.3.2 MySQL的数据库操作 224 14.3.3 表的创建 225 14.4 数据类型的介绍 228 14.5 索引与唯一值的介绍 229 14.6 数据的操作 230 14.6.1 表的修改 230 14.6.2 表的删除 231 14.6.3 数据的查询 ...
PHP中数组和链表的区别 从逻辑结构来看 1.、数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费;数组可以根据下标...
新的IO组件在处理磁盘中的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件...
[关于解压缩问题] 程序不做任何限制,如若失败请设置php内存限制。memory_limit 1000M [关于兼容性] 建议使用chrome firefox ie9+ 体验更完整。ie8以下基本上不做兼容处理。chrome支持文件夹拖拽上传。 [文件打开]...
为了运行不同的进程和应用程序,Pagefile.sys给物理内存分配了一些空间。在这些空间内允许交换数据页。 显然,系统在文件系统缓存中查找数据而不是在驱动器上搜索数据会提高系统的性能。太多的搜索操作会使处理器...
第2章 服务器平台安装和设备管理 2.1 硬件选择 2.1.1 CPU、RAM和主板与性能的关系 2.1.2 硬盘的选择 2.1.3 显示卡与监视器的选择 2.1.4 电源与UPS的选择 2.2 Linux的安装准备 2.2.1 Linux的获取 2.2.2 了解你的...
1、缓存支持内存缓存,如:memcache 缓存; 2、不重复生成和检查模版缓存,提升性能; 五、移动优先设计: 1、默认支持移动端访问自适应; 2、无需重复发文章,文章一键推送。 相关阅读...