搜索
首页后端开发php教程PHP变量的内存管理

PHP变量的内存管理

Apr 18, 2018 am 10:11 AM
php内存管理

这篇文章主要介绍了PHP变量的内存管理,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

每门计算机语言都需要一些容器来保存变量数据。在一些语言当中,变量都有特定的类型,如字符串,数组,对象等等。比如C和Pascal就属于这种。 而PHP则没有这样的类型。在PHP中,一个变量在某一行是字符串,可能到下一行就变成了数字。变量可以经常在不同的类型间轻易的转化,甚至是自动的转 换。PHP之所以成为一个简单并且强大的语言,很大一部分的原因是它拥有弱类型的变量。但是有些时候这也会带来一些有趣的问题。

在PHP内部,变量是存储在一个叫做zval的容器中。它不仅仅包含变量的值,也包含变量的类型。Python和PHP类似,也有一个标签标记变量类型。变量容器中包含一些Zend引擎用来区分是否引用的字段。同时它也包含这个值的引用计数。

变量存储在一个相当于关联数组的符号表中。这个数组以变量名为key,并且指向包含了这些变量的容器。如下图所示:


引用计数

PHP试着在变量拷贝(如 $a = $b )的时候变得聪明些。“=”也称为赋值操作符。当进行赋值操作时,Zend引擎不会创建一个新的变量窗口,而是增大变量窗口的 refcount 字段,你可以想象一下,当这个变量是一个巨大的字符串或一个巨大 的数组时,这将节约多少的内存。如下图所示:


第一步: 变量a,包含文本”this is”。默认情况下,引用计数等于1

第二步:将变量$a赋值给$b和$c。这里没有新的变量容器生成,仅仅是每次在变量赋值操作时将refcount加1。因为这里执行了两次赋值操作,所以refcount最后会变成3。

现在,也许你很想知道当变量$c改变时将发生什么。根据refcount的值的不同,它会有两种不同的处理方式。如果 refcount等于1,这个变量容器将更新它的值(也许同时会更新它的类型)。如果refcount大于1,将创建一个包含了新值(和类型)的变量容 器。如图2所示的第三步,$a变量所在的变量容器的refcount值被减去一,现在refcount的值是2,而新创建的容器的refcount的值为 1。当对一个变量使用unset函数时,这个变量所在的容器的refcount值将减去一,如图第4步所示。如果refcount的值少于1,Zend引 擎将翻译这个变量容器,如图第5步所示。

传递变量给函数(Passing Variables to Functions)

除了所有脚本共用的全局符号表以外,每个用户定义的函数在调用时都会创建一个属于自己的符号表,用来存放它自己的变量。当一个函数被调用后,Zend引擎 就会创建一个这样的符号表,当这个函数返回时这个函数表就会被释放。一个函数要么通过return语句返回,要么因为函数结束而返回(译者注:无返回的函 数默认会返回NULL)。如下图所示:


图3详细介绍了变量是如何传递给函数的。

第一步,我们将”thisis”赋给变量$a,然后我们将这个变量传递do_something()函数的$s变量。

第二步,你可以看到这与变量赋值的操作是一样的(与我们在前一小节提到的$b = $a类似),只是其存储在不同的符号表(函数符号表),并且引用计数加2,而不是加1。原因是函数栈也包含了这个变量容器的引用。

第三步,当我们赋新值给变量$s,原变量容器的refcount减1,并且创建一个包含了新值的变量容器。

第四步,我们通过return语句返回一个变量。返回的变量从全局符号表中获取一个实体并将其refcount的值增加1.当函数结束时,函数的符 号表将被销毁。在销毁的过程中,Zend引擎将遍历符号表中的每个变量,并将其refcount的值减少。当变量容器的refount的值变为0,这个变 量容器将会被销毁。如你所见,由于 PHP的引用计数机制,变量容器不是以拷贝的方式从函数返回。如果变量$s在第三步时没有被修改,则变量$a和$b将一直指向相同的变量容器(这个容器的 refcount为2)。在这种情况下,语句$a = “this is”将不会创建变量容器的副本。

相关推荐:

php变量之写时复制机制


以上是PHP变量的内存管理的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
您如何在PHP中创建和使用接口?您如何在PHP中创建和使用接口?Apr 30, 2025 pm 03:40 PM

本文解释了如何创建,实施和使用PHP中的接口,重点关注其对代码组织和可维护性的好处。

crypt()和password_hash()有什么区别?crypt()和password_hash()有什么区别?Apr 30, 2025 pm 03:39 PM

本文讨论了PHP中的crypt()和password_hash()之间的差异,以进行密码哈希,重点介绍其实施,安全性和对现代Web应用程序的适用性。

如何防止PHP中的跨站点脚本(XSS)?如何防止PHP中的跨站点脚本(XSS)?Apr 30, 2025 pm 03:38 PM

文章讨论了通过输入验证,输出编码以及使用OWASP ESAPI和HTML净化器之类的工具来防止PHP中的跨站点脚本(XSS)。

PHP中的自动加载是什么?PHP中的自动加载是什么?Apr 30, 2025 pm 03:37 PM

自动加载PHP会在需要时自动加载类文件,从而通过减少内存使用和增强代码组织来提高性能。最佳实践包括使用PSR-4和有效组织代码。

什么是PHP流?什么是PHP流?Apr 30, 2025 pm 03:36 PM

PHP流通过一致的API统一处理文件,网络插座和压缩格式等资源的处理,从而提高复杂性并增强代码灵活性和效率。

可以使用PHP上传的文件的最大大小是多少?可以使用PHP上传的文件的最大大小是多少?Apr 30, 2025 pm 03:35 PM

本文讨论了在PHP中管理文件上传大小的管理,重点是2MB的默认限制以及如何通过修改PHP.INI设置来增加它。

PHP中的无效类型是什么?PHP中的无效类型是什么?Apr 30, 2025 pm 03:34 PM

本文讨论了PHP 7.1中引入的PHP中的无效类型,允许变量或参数为指定类型或NULL。它突出显示了诸如提高可读性,类型安全性和明确意图的好处,并解释了如何声明

unset()和unlink()函数之间有什么区别?unset()和unlink()函数之间有什么区别?Apr 30, 2025 pm 03:33 PM

本文讨论了unset()和unlink()功能在编程中的差异,重点关注其目的和用例。 unset()从内存中删除变量,而unlink()从文件系统中删除文件。两者都对效率至关重要

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。