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中的内存管理与C语言有所不同。在PHP中,创建和操作字符串非常简单,如`$str = 'hello world';`,字符串可以被自由修改、拷贝和移动。相比之下,C语言中的静态字符...
【PHP内存管理详解】 在PHP编程中,内存管理是一个至关重要的环节,特别是对于那些长期运行的服务器程序,如Web服务器和PHP扩展模块。了解PHP如何分配和释放内存能帮助开发者编写更加高效和稳定的代码。 一、内存...
以下是一些关于PHP内存管理的核心知识点: 1. **内存限制(memory_limit)**: PHP的`memory_limit`配置项决定了脚本可以使用的最大内存。默认情况下,这个值可能设置为128MB,如`phpstudy-php.ini`中的设置所示。...
EasyTask的多进程功能是通过PCNTL(Process Control)扩展实现的,这个扩展允许PHP程序创建、管理和控制子进程。在EasyTask中,你可以设置多个子进程同时处理任务,这些子进程之间可以独立工作,互不影响,提高了...
通常,这可能涉及到对PHP内存管理函数如`malloc()`、`calloc()`、`realloc()`和`free()`的使用,或者通过PHP的内存管理扩展如ZEND_MM来实现。 此外,项目中包含的`os.sql`文件是数据库的SQL脚本,用于创建和初始化...
你可能听说过JAVA、.NET、PHP这些语言有垃圾回收的内存管理机制,但是很少会听到JavaScript也有自己的内存管理机制,JavaScript同样有着类似的垃圾回收功能。本文主要讲述了JavaScript的垃圾回收原理和具体的过程。 ...
PHP7对内存分配和回收策略进行了改进,例如使用引用计数来跟踪对象的生命周期。掌握这些内存管理技巧,有助于避免内存泄漏,提升程序的稳定性和效率。 线程安全在多进程或多线程环境中尤为重要。虽然PHP7默认是非...
本文将深入探讨如何使用PHP和C++通过IPC的两种常见机制——命名管道(Named Pipes)和共享内存(Shared Memory)来实现跨进程通信。这两种技术在高效率的系统设计中尤其重要。 首先,我们来看命名管道。命名管道是...
Libvirt是一个强大的开源库,用于管理和控制虚拟化平台,如KVM、Xen、QEMU等。这个PHP管理器利用Libvirt的API来执行各种操作,使非专业用户也能方便地进行虚拟机的日常维护。 该管理系统的核心功能包括: 1. **...
在PHP中,变量内存分配机制是一个核心概念,它影响数据的存储和处理方式。本文将深入探讨PHP变量内存分配的细节和相关问题。 首先,PHP是一种动态类型语言,变量的类型在运行时才确定,这与其他静态类型语言(如C++...
**PHP内存缓存技术memcached** 是一种广泛用于加速Web动态应用程序的分布式内存对象缓存系统。它通过存储数据在内存中,避免了反复查询数据库,显著提升了网站性能。memcached设计简洁,易于部署,支持多种编程语言...
- **Perl 和 PHP**:这两种语言都是典型的弱类型语言,它们支持动态类型转换,并允许在没有显式类型声明的情况下执行不同类型变量的操作。 #### 三、弱类型语言的优势与劣势 - **优势**:提高了开发效率,减少了...
这种工具通常通过调度器来管理这些任务,使得开发者可以方便地创建、管理和监控定时作业,而无需手动干预或借助外部调度服务。 【标签】"php"确认了这个框架是使用PHP编程语言开发的,这意味着它适用于已经采用PHP...
对于512MB系统,Linux内存管理器只被分配了一个较小大小的内存段,并且视频缓冲区的共享区域被移动到不同的位置以适应512MB内存的限制。具体步骤如下: **2.1 更改Linux内存大小** 将Linux内存大小设置为176MB。...
1. **用户管理**:包括用户注册、登录、权限分配、角色管理等功能,确保只有授权用户才能访问和操作后台。 2. **内容管理**:如文章、新闻、产品发布,分类管理,支持多级分类,方便维护网站内容。 3. **菜单管理*...
3. **使用安全的内存分配函数**:考虑使用像`malloc()`和`realloc()`这样的内存管理函数,它们在分配失败时会返回NULL,而不是溢出。 4. **异常处理**:添加适当的异常处理机制,当发生溢出时能及时捕获并处理,...
除了内存释放的改进,PHP 5.2.0 还对内存分配策略进行了调整。官方文档提到,PHP 5.2.0 将对 `memory_limit` 的检查从每次调用 `emalloc()` 函数时进行,改为了直接监测从系统请求的内存数据块(blocks)。这意味着...
这是因为在PHP中,内存管理是以一种优化的方式进行的,尽量减少与操作系统的交互,以提高内存分配的效率。 为了更好地理解这一点,可以使用PHP内置的memory_get_usage()函数,该函数返回当前脚本所占用的内存总量。...