博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php 回收周期(Collecting Cycles)
阅读量:6969 次
发布时间:2019-06-27

本文共 1591 字,大约阅读时间需要 5 分钟。

传统上,像以前的 php 用到的引用计数内存机制,无法处理循环的引用内存泄漏。然而 5.3.0 PHP 使用文章中的同步算法,来处理这个内存泄漏问题。

对算法的完全说明有点超出这部分内容的范围,将只介绍其中基础部分。首先,我们先要建立一些基本规则,如果一个引用计数增加,它将继续被使用,当然就不再在垃圾中。如果引用计数减少到零,所在变量容器将被清除(free)。就是说,仅仅在引用计数减少到非零值时,才会产生垃圾周期(garbage cycle)。其次,在一个垃圾周期中,通过检查引用计数是否减1,并且检查哪些变量容器的引用次数是零,来发现哪部分是垃圾。

为避免不得不检查所有引用计数可能减少的垃圾周期,这个算法把所有可能根(possible roots 都是zval变量容器),放在根缓冲区(root buffer)中(用紫色来标记),这样可以同时确保每个可能的垃圾根(possible garbage root)在缓冲区中只出现一次。仅仅在根缓冲区满了时,才对缓冲区内部所有不同的变量容器执行垃圾回收操作。看上图的步骤 A。

在步骤 B 中,算法使用深度优先搜索查找所有可能的根,找到后将每个变量容器中的引用计数减“1",为确保不会对同一个变量容器减两次"1",用灰色标记已减过“1”的。在步骤 C 中,算法再一次对每个根节点使用深度优先搜索,检查每个变量容器的引用计数。如果引用计数是 0 ,变量容器用白色来标记(图中的蓝色)。如果引用次数大于0,则恢复在这个点上使用深度优先搜索而将引用计数减”1“的操作(即引用计数加“1”),然后将它们重新用黑色标记。在最后一步 D 中,算法遍历根缓冲区以从那里删除变量容器根(zval roots),同时,检查是否有在上一步中被白色标记的变量容器。每个被白色标记的变量容器都被清除。

现在,你已经对这个算法有了基本了解,我们回头来看这个如何与PHP集成。默认的,PHP的垃圾回收机制是打开的,然后有个 php.ini 设置允许你修改它:zend.enable_gc 

当垃圾回收机制打开时,每当根缓存区存满时,就会执行上面描述的循环查找算法。根缓存区有固定的大小,可存10,000个可能根,当然你可以通过修改PHP源码文件Zend/zend_gc.c中的常量GC_ROOT_BUFFER_MAX_ENTRIES,然后重新编译PHP,来修改这个10,000值。当垃圾回收机制关闭时,循环查找算法永不执行,然而,可能根将一直存在根缓冲区中,不管在配置中垃圾回收机制是否激活。

当垃圾回收机制关闭时,如果根缓冲区存满了可能根,更多的可能根显然不会被记录。那些没被记录的可能根,将不会被这个算法来分析处理。如果他们是循环引用周期的一部分,将永不能被清除进而导致内存泄漏。

即使在垃圾回收机制不可用时,可能根也被记录的原因是,相对于每次找到可能根后检查垃圾回收机制是否打开而言,记录可能根的操作更快。不过垃圾回收和分析机制本身要耗不少时间。

除了修改配置zend.enable_gc ,也能通过分别调用  函数来打开和关闭垃圾回收机制。调用这些函数,与修改配置项来打开或关闭垃圾回收机制的效果是一样的。即使在可能根缓冲区还没满时,也能强制执行周期回收。你能调用函数达到这个目的。这个函数将返回使用这个算法回收的周期数。

允许打开和关闭垃圾回收机制并且允许自主的初始化的原因,是由于你的应用程序的某部分可能是高时效性的。在这种情况下,你可能不想使用垃圾回收机制。当然,对你的应用程序的某部分关闭垃圾回收机制,是在冒着可能内存泄漏的风险,因为一些可能根也许存不进有限的根缓冲区。因此,就在你调用函数释放内存之前,先调用函数可能比较明智。因为这将清除已存放在根缓冲区中的所有可能根,然后在垃圾回收机制被关闭时,可留下空缓冲区以有更多空间存储可能根。

转载地址:http://ifisl.baihongyu.com/

你可能感兴趣的文章
MySQL索引分析
查看>>
20170829
查看>>
android项目获得所有运行程序
查看>>
Volley框架学习
查看>>
css中常用的标签
查看>>
android studio无线真机调试------Android
查看>>
jsp指令与动作
查看>>
C++中关键字的理解--Static
查看>>
简述Core Location定位功能
查看>>
html搜索,文中的关键字变色
查看>>
Python标准库_ sys,random,time
查看>>
[Android开发Tips]Bean的定义
查看>>
less
查看>>
PrestaShop 网站后台配置(三)
查看>>
【Win8启动后自动进入传统桌面设置】
查看>>
GP通过外部表装载数据时遇到ERROR:extra data after last expected column解决方法
查看>>
hdu2639,第K优决策
查看>>
hdu1166 敌兵布阵
查看>>
gcd(辗转相除法)
查看>>
多个Silverlight应用程序如何共享一个DomainService
查看>>