资讯专栏INFORMATION COLUMN

PHP回收周期

Astrian / 847人阅读

摘要:原文回收周期,增加一篇论文在底部。就是说,仅仅在引用计数减少到非零值时,才会产生垃圾周期。如果他们是循环引用周期的一部分,将永不能被清除进而导致内存泄漏。这个函数将返回使用这个算法回收的周期数。引用计数系统中的同步周期回收

原文:回收周期(Collecting Cycles) ,增加一篇论文在底部。

以下过程仅对数组和对象类型起作用。

传统上,像以前的 php 用到的引用计数内存机制,无法处理循环的引用内存泄漏。然而 5.3.0 PHP 使用文章» 引用计数系统中的同步周期回收(Concurrent Cycle Collection in Reference Counted Systems)中的同步算法,来处理这个内存泄漏问题。

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

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

在步骤 B 中,模拟删除每个紫色变量。模拟删除时可能将不是紫色的普通变量引用数减”1″,如果某个普通变量引用计数变成0了,就对这个普通变量再做一次模拟删除。每个变量只能被模拟删除一次,模拟删除后标记为灰(原文说确保不会对同一个变量容器减两次”1″,不对的吧)。

在步骤 C 中,模拟恢复每个紫色变量。恢复是有条件的,当变量的引用计数大于0时才对其做模拟恢复。同样每个变量只能恢复一次,恢复后标记为黑,基本就是步骤 B 的逆运算。这样剩下的一堆没能恢复的就是该删除的蓝色节点了,在步骤 D 中遍历出来真的删除掉。

算法中都是模拟删除、模拟恢复、真的删除,都使用简单的遍历即可(最典型的深搜遍历)。复杂度为执行模拟操作的节点数正相关,不只是紫色的那些疑似垃圾变量。

现在,你已经对这个算法有了基本了解,我们回头来看这个如何与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 ,也能通过分别调用gc_enable() 和 gc_disable()函数来打开和关闭垃圾回收机制。调用这些函数,与修改配置项来打开或关闭垃圾回收机制的效果是一样的。即使在可能根缓冲区还没满时,也能强制执行周期回收。你能调用gc_collect_cycles()函数达到这个目的。这个函数将返回使用这个算法回收的周期数。

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

引用计数系统中的同步周期回收(ConcurrentCycleCollection)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30169.html

相关文章

  • 【转】浅谈PHP5中垃圾回收算法(Garbage Collection)的演化

    摘要:所有这些类型,在内部统一用一个叫做的结构表示,在源代码中这个结构名称为。的具体定义在源代码的文件中,下面是相关代码的摘录。 【转】浅谈PHP5中垃圾回收算法(Garbage Collection)的演化 前言 PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源的分配与释放(使用C编写PHP或Zend扩展除外),这就意味着PHP本身实现了垃圾回收机制(Garbage C...

    AdolphLWQ 评论0 收藏0
  • php底层原理之垃圾回收机制

    摘要:总结垃圾回收机制以的引用计数机制为基础以前只有该机制同时使用根缓冲区机制,当发现有存在循环引用的时,就会把其投入到根缓冲区,当根缓冲区达到配置文件中的指定数量后,就会进行垃圾回收,以此解决循环引用导致的内存泄漏问题开始引入该机制 php垃圾回收机制,对于PHPer来说是一个不陌生但是又不是很熟悉的内容。那么php是怎么实现对不需要的内存进行回收的呢? php变量的内部存储结构 首先还是...

    light 评论0 收藏0
  • PHP的生命周期

    摘要:的启动和终止请求之前的开始阶段模块初始化阶段。的生命周期单进程生命周期多进程生命周期多线程的生命周期是一种比较特殊的,容许你在语言中调用提供的函数。不太了解,明天看一下综述理一下的生命周期,以及整个执行过程。 PHP的架构图 showImg(https://segmentfault.com/img/remote/1460000013321599?w=514&h=525); SAPI S...

    sf190404 评论0 收藏0
  • PHP生命周期

    摘要:的整个生命周期被划分为以下几个阶段模块初始化阶段请求初始化阶段执行脚本阶段请求关闭阶段模块关闭阶段。 PHP的整个生命周期被划分为以下几个阶段:模块初始化阶段(module startup)、请求初始化阶段(request startup)、执行脚本阶段(executescript)、请求关闭阶段(request shutdown)、模块关闭阶段(module shutdown)。根据...

    wh469012917 评论0 收藏0
  • php内核阅读(2)--浅谈 gc回收机制

    摘要:垃圾回收所谓垃圾就是指通过循环引用自己引用自己,目前只在类型中有出现的形式而导致永远不为。当出现垃圾之后,的引擎有对应的垃圾回收机制。触发这个机制的时机是每次出现减少时候。 自嘲)。。。。。2333,我觉得这是因为在php语言层面就帮我们解决了内存回收的问题,但这让我在和java大牛们吹牛逼的时候,听到什么内存泄露。。。。(纳尼,我tmd怎么从来没遇见过)一脸懵逼。 本人小菜,如果下面...

    wemallshop 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<