深入解析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基础学习笔记
Mar 18 PHP
php不用内置函数对数组排序的两个算法代码
Feb 08 PHP
php短域名转换为实际域名函数
Jan 17 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
Nov 10 PHP
PHP中的生成XML文件的4种方法分享
Oct 06 PHP
探寻PHP脚本不报错的原因
Jun 12 PHP
php中call_user_func函数使用注意事项
Nov 21 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
Nov 29 PHP
php判断对象是派生自哪个类的方法
Jun 20 PHP
WordPress开发中用于标题显示的相关函数使用解析
Jan 07 PHP
Zend Framework框架路由机制代码分析
Mar 22 PHP
PHP多进程之pcntl_fork的实例详解
Oct 15 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
深入Apache与Nginx的优缺点比较详解
2013/06/17 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
PHP数组内存利用率低和弱类型详细解读
2017/08/10 PHP
thinkPHP实现基于ajax的评论回复功能
2018/06/22 PHP
YII框架行为behaviors用法示例
2019/04/26 PHP
Array.prototype.slice 使用扩展
2010/06/09 Javascript
js中各浏览器中鼠标按键值的差异
2011/04/07 Javascript
最新28个很棒的jQuery 教程
2011/05/28 Javascript
js获取select默认选中的Option并不是当前选中值
2014/05/07 Javascript
jQuery实现视频作为全屏幕背景
2014/12/18 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
javascript实现的左右无缝滚动效果
2016/09/19 Javascript
JS函数修改html的元素内容,及修改属性内容的方法
2016/10/28 Javascript
JavaScript动态数量的文件上传控件
2016/11/18 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
2018/02/06 Javascript
JavaScript常用8种数组去重代码实例
2020/09/09 Javascript
python模拟登录百度贴吧(百度贴吧登录)实例
2013/12/18 Python
Python实现的最近最少使用算法
2015/07/10 Python
Flask和Django框架中自定义模型类的表名、父类相关问题分析
2018/07/19 Python
python3 map函数和filter函数详解
2019/08/26 Python
解决Python使用列表副本的问题
2019/12/19 Python
解决CSS3 transition-delay 属性默认值0不带单位失效的问题
2020/10/29 HTML / CSS
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
Boden澳大利亚官网:英国在线服装公司
2018/08/05 全球购物
PatPat阿根廷:妈妈们的购物平台
2019/05/30 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
阿里巴巴的Oracle DBA笔试题答案-SQL tuning类
2016/04/03 面试题
文秘专业自荐信
2013/10/14 职场文书
面试后感谢信怎么写
2014/02/01 职场文书
《乌鸦和狐狸》教学反思
2014/02/08 职场文书
工程技术员岗位职责
2014/03/02 职场文书
优秀德育工作者事迹材料
2014/05/07 职场文书
邹越感恩父母演讲稿
2014/08/28 职场文书
交通事故赔偿协议书
2014/10/16 职场文书
党员民主评议自我评价
2014/10/20 职场文书
2014年服务行业工作总结
2014/11/18 职场文书