手机版

PHP垃圾收集机制解读

时间:2021-09-08 来源:互联网 编辑:宝哥软件园 浏览:

PHP的基本GC概念,PHP语言和其他语言一样,有垃圾收集机制。所以我们今天要给大家解释的是PHP的垃圾收集机制。希望对大家有帮助。PHP strtotime应用的经验PHP memory_get_usage()管理内存phpset全局变量应用问题详解phpset()函数销毁变量教你快速实现PHP全站权限验证I. PHP垃圾收集器(简称GC)在PHP中,当没有变量指向这个对象时,这个对象就变成了垃圾。PHP会在内存中破坏它;这是PHP的GC垃圾处理机制,防止内存溢出。当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中的所有对象也会同时被销毁。通常,gc进程从每个会话开始运行。垃圾收集的目的是在会话文件过期后自动销毁和删除它们。第二,当回收垃圾对象时,会执行_ _ _ _ _销毁/取消设置_ _ _ _ _销毁()析构函数。Unset销毁指向对象的变量,而不是对象。Session和PHP垃圾收集机制由于PHP的工作机制,它没有守护线程定期扫描Session信息,判断是否无效。当一个有效的请求发生时,PHP将根据全局变量session.gc_probability和session.gc _ differentiator的值来决定是否启用GC。默认情况下,Session.gc _ probability=1,session.gc _ differentiator=100,这意味着有1%的可能性启动gc(这意味着100个请求中只有一个gc将以100个请求中的一个启动)。PHP垃圾收集机制的工作是扫描所有的会话信息。通过从当前时间中减去会话的上次修改时间,将其与session.gc_maxlifetime参数进行比较。如果生存期超过gc_maxlifetime(默认为24分钟),会话将被删除。但是,如果您的Web服务器有多个站点,垃圾收集在处理会话时可能会有意外的结果。原因是GC在工作时没有区分不同站点的会话。那么这个时候如何解决这个问题呢?1.修改session.save_path,或者使用session_save_path()将每个站点的会话保存到一个特殊的目录中。2.提供气相色谱的启动速率。自然,PHP垃圾收集机制的启动率会增加,系统的性能也会相应下降,不推荐使用。3.确定代码中当前会话的生存时间,并使用session_destroy()将其删除。

引用计数的基本知识每个php变量都存在于一个名为“zval”的变量容器中。除了变量的类型和值之外,zval变量容器还包含两个字节的额外信息。第一个是“is_ref”,这是一个bool值,用于标识变量是否属于引用集。通过这个字节,只有php引擎可以区分普通变量和引用变量。因为php允许用户使用自定义引用,所以zval变量容器也有一个内部引用计数机制来优化内存使用。第二个额外的字节是“refcount”,它指示指向这个zval变量容器的变量(也称为符号)的数量。

当变量被赋予一个常量值时,将生成一个zval变量容器,如下面的示例:所示

?php $a='新字符串';在上面的例子中,新的变量是A,它是在当前范围内生成的,并且生成了一个类型字符串和值“new string”的变量容器。在额外的两个字节的信息中,“is_ref”默认设置为false,因为没有生成自定义引用,而“refcount”设置为1,因为只有一个变量使用此变量容器。调用xdebug检查变量内容33366。

?php $a='新字符串';xdebug _ debug _ zval(' a ');上面的代码将输出:

A: (refcount=1,is _ ref=0)=' new string '向变量a添加引用计数。

?php $a='新字符串';$ b=$ a;xdebug _ debug _ zval(' a ');上面的代码将输出:

A: (refcount=2,is _ ref=0)=' new string '此时引用数为2,因为同一个变量容器关联了变量A和变量b,当没有必要时,Php不会复制生成的变量容器。当“refcount”变为0时,变量容器将被销毁。当任何容易与变量相关联的变量离开其作用域时(例如,函数的执行结束),或者对该变量调用unset()函数时,“refcount”将减少1,下面的示例可以解释3360。

?php $a='新字符串';$ b=$ c=$ a;xdebug _ debug _ zval(' a ');联合国索赔集(b,c美元);xdebug _ debug _ zval(' a ');上面的代码将输出:

A: (refcount=3,is _ ref=0)=' new string ' a :(ref count=1,is _ ref=0)=' new string '如果我们现在执行unset($a),$a),这个包含$的类型和值的容器将从内存中删除

复合类型(复合类型)

当考虑像数组和对象这样的复合类型时,事情变得有点复杂。与标量值不同,数组和对象的变量在它们自己的符号表中有它们的成员或属性。这意味着下面的示例将生成三个zval变量容器。

?php $a=array('意为'='life ',' number '=42);xdebug _ debug _ zval(' a ');上述代码输出:

A: (refcount=1,is _ ref=0)=数组('含义'=(refcount=1,is _ ref=0)=' life ',' number'=(refcount=1,is _ ref=0)=42)这三个zval变量容器是332

特例,当添加数组本身作为数组元素时

?php $a=数组(' one ');$ a[]=$ a;xdebug _ debug _ zval(' a ');上述代码输出的结果是:

A: (refcount=2,is _ ref=1)=array (0=(refcount=1,is _ ref=0)=' one ',1=(refcount=2,is _ ref=1)=.)您可以看到数组A及其元素a[1]指向

当对数组$a调用unset函数时,$a的refcount变为1,并且发生内存泄漏

清理变量容器的问题虽然在某个范围内不再有任何符号指向这个结构(即变量容器),但是这个容器不能被消除,因为数组元素“1”仍然指向数组本身。因为没有其他符号指向它,用户无法清除这个结构,这将导致内存泄漏。幸运的是,php会在请求结束时清除这个数据结构,但是在php清除它之前,它会消耗大量的内存空间。

回收循环5.3.0PHP使用了一种新的同步循环回收算法来处理上面提到的内存泄漏问题

首先,我们需要建立一些基本规则:如果引用计数增加,它将继续被使用,当然,它不会是垃圾。如果参考技术减少到零,它所在的变量容器将是自由的。也就是说,只有当引用计数减少到非零值时,才会发生垃圾循环。其次,在垃圾周期中,检查引用计数是否减少了1,以及检查了哪些变量。

2015810114143348.png  (429552)

为了避免必须检查所有引用计数可能减少的垃圾周期,该算法将所有可能的根(所有可能的根都是zval变量容器)放入根缓冲区(用紫色标记),这可以确保每个可能的垃圾根在缓冲区中只出现一次。只有当根缓冲区已满时,才会对缓冲区中所有不同的变量容器执行垃圾收集操作。

版权声明:PHP垃圾收集机制解读是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。