`
student_lp
  • 浏览: 428699 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

php垃圾回收之回收策略和算法

阅读更多

一、垃圾回收实现方式

     在以前的php中用到的是引用计数机制处理垃圾回收问题,但是这个机制存在一个弊端,就是无法处理循环引用引起的内存泄露。然而在php5.3.0以后的版本中(包含5.3.0)使用了专门GC机制(同步算法)清理垃圾,来处理这个内存泄露问题。下面就是介绍它是如何实现的:

    首先要了解几个基本的准则:

1:如果一个zval的refcount增加,那么此zval还在使用,不属于垃圾。

2:如果一个zval的refcount减少到0, 那么zval可以被释放掉,属于垃圾。

3:如果一个zval的refcount减少之后大于0,那么此zval还不能被释放,此zval可能成为一个垃圾。

     只有在准则3下,GC才会把zval收集起来,然后通过新的算法来判断此zval是否为垃圾。那么如何判断这么一个变量是否为真正的垃圾呢?简单的说,就是对此zval中的每个元素进行一次refcount减1操作,操作完成之后,如果zval的refcount=0,那么这个zval就是一个垃圾。这个原理咋看起来很简单,但是又不是那么容易理解,下面通过结构图来深入理解:


     A:为了避免每次变量的refcount减少的时候都调用GC的算法进行垃圾判断,此算法会先把所有前面准则3情况下的zval节点放入一个节点(root)缓冲区(root buffer),并且将这些zval节点标记成紫色,同时算法必须确保每一个zval节点在缓冲区中之出现一次。当缓冲区被节点塞满的时候,GC才开始开始对缓冲区中的zval节点进行垃圾判断。

     B:当缓冲区满了之后,算法以深度优先对每一个节点所包含的zval进行减1操作,为了确保不会对同一个zval的refcount重复执行减1操作,一旦zval的refcount减1之后会将zval标记成灰色。需要强调的是,这个步骤中,起初节点zval本身不做减1操作,但是如果节点zval中包含的zval又指向了节点zval(环形引用),那么这个时候需要对节点zval进行减1操作。

     C:算法再次以深度优先判断每一个节点包含的zval的值,如果zval的refcount等于0,那么将其标记成白色(代表垃圾),如果zval的refcount大于0,那么将对此zval以及其包含的zval进行refcount加1操作,这个是对非垃圾的还原操作,同时将这些zval的颜色变成黑色(zval的默认颜色属性)

     D:遍历zval节点,将C中标记成白色的节点zval释放掉。

二、举例详解垃圾回收过程

     通过上面的说明,大家可能已经有了一定的印象,那实际应用中是如何具体操作的呢?下面就通过例子说明:

    ①在刚刚声明变量并赋值的情况下,其实就相当于准则1(如果一个zval的refcount增加,那么此zval还在使用,不属于垃圾),变量不是垃圾,也不会进行gc检查。

$a = "one";
$b = array();
$b[] = $a;
$b[] = & $b;
$c = "two";
//声明了三个变量$a、$b、$c。这个时候refcount都是增加的情况,变量不是垃圾也不会放入到root缓冲器等待垃圾检查。
xdebug_debug_zval( 'a' );  
xdebug_debug_zval( 'b' );  
xdebug_debug_zval( 'c' );  
//输出分别如下:
a: (refcount=2, is_ref=0)='one'
b: (refcount=2, is_ref=1)=array (  
   0 => (refcount=2, is_ref=0)='one',  
   1 => (refcount=2, is_ref=1)=... 
)  
c: (refcount=1, is_ref=0)='two'

   ②在上面的基础上,我们调用了unset()函数释放变量b和c。如下:

unset($b);
unset($c);
xdebug_debug_zval( 'a' ); 
//输出如下:
a: (refcount=2, is_ref=0)='one'

     调用unset函数后,$b和$c对应容器中的refcount都会减1,但是他们的效果却不相同:先看$c调用unset($c)后,$c的refcount就编程了0,符合准则2,则$c对应的zval容器就是垃圾会被回收;再看$b调用unset($b)后,但是$b的第1个引用仍然指向$b所对应的zval容器,只不过$b对应的zval容器的refcount会减1,值会从2变成1。这时候容器的refcount虽然减1,但仍然不为零,则符合准则3,会把$b对应的zval,放入到root缓冲区中。等待gc垃圾校验操作,也就是进入到了(二)中的(A)情况。

     ③在往后的操作就是(二)中描述的了。经历(二)中的ABCD过程后,变量$b对应的zval容器会被释放,完成了垃圾回收,也解决了循环引用的内存泄露问题。

三、垃圾回收器配置使用

     在PHP中,GC默认是开启的,你可以通过ini文件中的 zend.enable_gc 项来开启或则关闭GC。当GC开启的时候,垃圾分析算法将在节点缓冲区(roots buffer)满了之后启动。缓冲区默认可以放10,000个值,当然你也可以通过修改Zend/zend_gc.c中的GC_ROOT_BUFFER_MAX_ENTRIES 来改变这个数值,需要重新编译链接PHP。当GC关闭的时候,垃圾分析算法就不会运行,但是相关节点还会被放入节点缓冲区,这个时候如果缓冲区节点已经放满,那么新的节点就不会被记录下来,这些没有被记录下来的节点就永远也不会被垃圾分析算法分析。如果这些节点中有循环引用,那么有可能产生内存泄漏。之所以在GC关闭的时候还要记录这些节点,是因为简单的记录这些节点比在每次产生节点的时候判断GC是否开启更快,另外GC是可以在脚本运行中开启的,所以记录下这些节点,在代码运行的某个时候如果又开启了GC,这些节点就能被分析算法分析。当然垃圾分析算法是一个比较耗时的操作。

    在PHP代码中我们可以通过gc_enable()和gc_disable()函数来开启和关闭GC,也可以通过调用gc_collect_cycles()在节点缓冲区未满的情况下强制执行垃圾分析算法。这样用户就可以在程序的某些部分关闭或则开启GC,也可强制进行垃圾分析算法。 

     

  • 大小: 29.9 KB
分享到:
评论

相关推荐

    php 垃圾回收算法原理, 英文版

    论文

    66道算法题目+php解题+java解题.zip

    Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。

    PHP 进程池与轮询调度算法实现多任务的示例代码

    phper 请了解进程调度策略,CPU 时间片,进程控制【创建,销毁,回收,进程信号】与及进程运行流程和基本的进程组,信号中断原理,以及进程之间的关系。 关于进程的更多内容可参考本人前面撸过的文章或是百度了解。...

    网软志成分类信息网站系统.net官方商业版

    专业的过滤注入式入侵、严密高效的防护算法和监控程序构成站点严密的安全体系。 强大而完善的功能 完善的多重无限分类,分站、分类栏目均可生成html页面、可选用的所见即所得编辑器、自定义信息发布字段、分站完全...

    生活分类信息发布网站的优秀网站管理系统正式版

    专业的过滤注入式入侵、严密高效的防护算法和监控程序构成站点严密的安全体系。 强大而完善的功能 完善的多重无限分类,分站、分类栏目均可生成html页面、可选用的所见即所得编辑器、自定义信息发布字段、分站完全...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例045 自定义数字的加密/解密算法 76 实例046 比较两个时间戳的大小 77 实例047 使用条件运算符判断数字的奇偶性 78 实例048 判断用户是否具有后台管理权限 79 实例049 打印随机组合生日祝福语 80 实例050 打印...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例045 自定义数字的加密/解密算法 76 实例046 比较两个时间戳的大小 77 实例047 使用条件运算符判断数字的奇偶性 78 实例048 判断用户是否具有后台管理权限 79 实例049 打印随机组合生日祝福语 80 实例050 打印...

    PHP 多进程与信号中断实现多任务常驻内存管理实例方法

    父子进程的调度由操作系统来负责,具体先调度子进程还是父进程由系统的调度算法决定,当然可以在父进程加上延时或是调用进程回收函数 pcntl_wait 可以先让子进程先运行,进程回收的目的是释放进程创建时占用的内存...

    leetcode卡-article:存放自己的一些文章或总结的

    Java的垃圾回收机制回顾及常用JVM调用参数配置例子 可视化系统相关 Superset 可视化BI系统部署安装及简单使用 Metabase 可视化BI系统部署安装及简单使用 Redash 可视化BI系统部署安装及简单使用 CBoard 可视化BI系统...

    阿里云javasdk源码-gocn-daily-news:GoCN每日新闻

    Golang垃圾回收 从PHP到Go 从C/C++/Golang谈计算机语言的巨大进步 使用kubernetes自动部署Golang程序 使用Go 机器学习库来进行数据分析 用make文件来全自动开发go程序 如何提高物联网程序操作数据库大批量执行DML...

    Web服务器三剑客运维配置实战 Nginx+JVM+Tomcat+HTTP协议.zip

    ├─4.05 java细腻及讲解-jvm虚拟机常识-常用垃圾回收算法.mp4 ├─4.06 jvm运维实用排障工具.mp4 ├─4.07 jvm运维实用排障工具-jps-jstack.mp4 ├─4.08 jvm运维实用排障工具-jinfo-jstat.mp4 ├─4.09 jvm运维...

    免费恢复预览的专业数据恢复图片恢复软件

    数据恢复 硬盘数据恢复 内存卡数据恢复 存储卡数据恢复 U盘数据恢复 SD卡数据恢复 移动硬盘数据恢复 手机数据恢复 格式化数据恢复 GHOST数据恢复 电脑数据恢复 回收站数据恢复 相机卡数据恢复 专业数据恢复 分区丢失...

    CmsTop 内容管理系统大众版 v1.0.0.800 Final.rar

    CmsTop大众版具有全面的内容展现形式、人性化的管理操作体验、周全的数据整合、标签化的模板数据调用、模块化开发与二次开发、千万级数据承载...网站的资讯频道以及网络媒体、事业单位、学校和企业的网站发布与管理需求...

    Collector资料收集管理器

    3、修改加载图标算法,超速打开数据库。 打开数据库后请使用修复图标功能,再次打开才能体现。 2.5版本 1、添加附件功能; 2、自定义抓图压缩率。 3、添加下载数据库功能。 4、创建或清除快捷方式无须重新...

    网管教程 从入门到精通软件篇.txt

    ★详细的xp修复控制台命令和用法!!! 放入xp(2000)的光盘,安装时候选R,修复! Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小...

Global site tag (gtag.js) - Google Analytics