深入解析PHP垃圾回收机制对内存泄露的处理


Posted in PHP onJune 14, 2013

上次说到了refcount和is_ref,这里来说说内存泄露的情况

$a = array(1, 2, &$a);
unset($a);

在老的PHP版本中,这里就会出现内存泄露,分析如下:

执行第一行,可以知道$a和$a[2]指向的zval refcount=2,is_ref=1

然后执行第二行,$a将会从符号表中被删除,同时指向的zval的refcount--,此时refcount=1,因为refcount!=0,故此zval不会被当做垃圾回收,但是此时我们却失去了$a[2]指向这个zval的入口,因此这个zval成了一块内存垃圾

同样的道理可以发生在类内部引用里,例如

$a = new Man();
$a->self = &$a;
unset($a);

那么如何解决这种问题呢,新的GC机制采用了一个算法来解决这个问题

PHP有一个root buffer用来存储zval的节点信息,当root buffer满了或者手动调用gc函数时,GC算法启动

对于一个数组或者类类型的zval而言,在垃圾回收机制启动时,算法会对该zval的数组/类内部的元素/成员的zval进行一次遍历并将refcount减1,如果说遍历完成后该zval的refcount被减为0,则说明这个zval是一个内存垃圾,他将被销毁,见下面的例子

$a = array(1, 2, &$a, &$a);
unset($a);

容易知道$a指向的zval,假设为z1的refcount=3,is_ref=1

当unset($a)执行的时候,$a就已经从符号表中删去,同时我们也失去了访问z1的入口,此时z1 refcount=2,is_ref=1

当GC启动时,会对该z1的数组元素的zval的refcount进行遍历减1,遍历到a[2]时,z1 refcount--, a[3]时 z1 refcount--,此时z1 refcount = 0,即可将z1标记为内存垃圾,算法后将其回收

总结来说可以这么表述:若一个数组类型的zval,对他的元素zval进行一次遍历,同时将遍历到的zval的refcount--,如果最后refcount=0的zval,就是垃圾,需要被回收

PHP 相关文章推荐
PHP中在数据库中保存Checkbox数据(1)
Oct 09 PHP
PHP与已存在的Java应用程序集成
Oct 09 PHP
php 用checkbox一次性删除多条记录的方法
Feb 23 PHP
php中sql注入漏洞示例 sql注入漏洞修复
Jan 24 PHP
codeigniter自带数据库类使用方法说明
Mar 25 PHP
一个php短网址的生成代码(仿微博短网址)
May 07 PHP
PHP使用CURL实现多线程抓取网页
Apr 30 PHP
PHP+Ajax实时自动检测是否联网的方法
Jul 01 PHP
PHP实现二维数组根据key进行排序的方法
Dec 30 PHP
thinkPHP+phpexcel实现excel报表输出功能示例
Jun 06 PHP
Yii2框架自定义验证规则操作示例
Feb 08 PHP
PHP实用小技巧之调用录像的方法
Dec 05 PHP
Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
Jun 14 #PHP
解析php中两种缩放图片的函数,为图片添加水印
Jun 14 #PHP
PHP操作Memcache实例介绍
Jun 14 #PHP
解析PHP处理换行符的问题 \r\n
Jun 13 #PHP
基于PHP5魔术常量与魔术方法的详解
Jun 13 #PHP
基于PHPExcel的常用方法总结
Jun 13 #PHP
深入PHP FTP类的详解
Jun 13 #PHP
You might like
不用mod_rewrite直接用php实现伪静态化页面代码
2008/10/04 PHP
PHP设置images目录不充许http访问的方法
2016/11/01 PHP
php指定长度分割字符串str_split函数用法示例
2017/01/30 PHP
AJAX 网页保留浏览器前进后退等功能
2011/02/12 Javascript
提升你网站水平的jQuery插件集合推荐
2011/04/19 Javascript
关于js拖拽上传 [一个拖拽上传修改头像的流程]
2011/07/13 Javascript
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
2013/02/18 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
2013/04/09 Javascript
javascript检测对象中是否存在某个属性判断方法小结
2013/05/19 Javascript
jQuery之折叠面板的深入解析
2013/06/19 Javascript
Extjs grid panel自带滚动条失效的解决方法
2014/09/11 Javascript
js获取json元素数量的方法
2015/01/27 Javascript
JS实现的数组全排列输出算法
2015/03/19 Javascript
JavaScript转换二进制编码为ASCII码的方法
2015/04/16 Javascript
jQuery文字横向滚动效果的实现代码
2016/05/31 Javascript
轻松掌握JavaScript策略模式
2016/08/25 Javascript
微信开发 消息推送实现代码
2016/10/21 Javascript
vue.js选中动态绑定的radio的指定项
2017/06/02 Javascript
vue文件树组件使用详解
2018/03/29 Javascript
bootstrap table表格插件之服务器端分页实例代码
2018/09/12 Javascript
node.js监听文件变化的实现方法
2019/04/17 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
django允许外部访问的实例讲解
2018/05/14 Python
python range()函数取反序遍历sequence的方法
2018/06/25 Python
Python基于滑动平均思想实现缺失数据填充的方法
2019/02/21 Python
python正则爬取某段子网站前20页段子(request库)过程解析
2019/08/10 Python
jupyter notebook 实现matplotlib图动态刷新
2020/04/22 Python
css3动画 小球滚动 js控制动画暂停
2019/11/29 HTML / CSS
俄罗斯三星品牌商店:Samsungstore
2020/04/05 全球购物
学校七一活动方案
2014/01/19 职场文书
另类冲刺标语
2014/06/24 职场文书
人事主管岗位职责说明书
2014/07/30 职场文书
廉政教育的心得体会
2014/09/01 职场文书
乡村教师党员四风问题对照检查材料思想汇报
2014/10/08 职场文书
2016感恩母亲节校园广播稿
2015/12/17 职场文书