深入解析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 简单数组排序实现代码
Aug 05 PHP
php文件服务实现虚拟挂载其他目录示例
Apr 17 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
Jun 25 PHP
php调用新浪短链接API的方法
Nov 08 PHP
php计算两个坐标(经度,纬度)之间距离的方法
Apr 17 PHP
PHP打印输出函数汇总
Aug 28 PHP
PHP数据库操作三:redis用法分析
Aug 16 PHP
基于PHP-FPM进程池探秘
Oct 17 PHP
php微信开发之谷歌测距
Jun 14 PHP
Laravel等框架模型关联的可用性浅析
Dec 15 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
Mar 24 PHP
关于PHP中interface的用处详解
Jul 26 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
php中++i 与 i++ 的区别
2012/08/08 PHP
php 生成短网址原理及代码
2014/01/23 PHP
php生成图片验证码的实例讲解
2015/08/03 PHP
joomla数据库操作示例代码
2016/01/06 PHP
THinkPHP获取客户端IP与IP地址查询的方法
2016/11/14 PHP
Zend Framework基于Command命令行建立ZF项目的方法
2017/02/18 PHP
PHP基于XMLWriter操作xml的方法分析
2017/07/17 PHP
用js实现预览待上传的本地图片
2007/03/15 Javascript
js限制文本框为整数和货币的函数代码
2010/10/13 Javascript
HTML DOM的nodeType值介绍
2011/03/31 Javascript
js setTimeout 常见问题小结
2013/08/13 Javascript
原生js ActiveXObject获取execl里面的值
2013/11/01 Javascript
jquery 快速回到页首的方法
2013/12/05 Javascript
Extjs表单常见验证小结
2014/03/07 Javascript
一个php+js实时显示时间问题
2015/10/12 Javascript
jQuery中使用animate自定义动画的方法
2016/05/29 Javascript
浅谈javascript中关于日期和时间的基础知识
2016/07/13 Javascript
bootstrap table动态加载数据示例代码
2017/03/25 Javascript
jQuery实现的滑块滑动导航效果示例
2018/06/04 jQuery
浅析vue给不同环境配置不同打包命令
2018/08/17 Javascript
使用gulp构建前端自动化的方法示例
2018/12/25 Javascript
vue中轮训器的使用
2019/01/27 Javascript
javascript实现打砖块小游戏(附完整源码)
2020/09/18 Javascript
Python编程中使用Pillow来处理图像的基础教程
2015/11/20 Python
Python中Django发送带图片和附件的邮件
2017/03/31 Python
python 矩阵增加一行或一列的实例
2018/04/04 Python
解决python字典对值(值为列表)赋值出现重复的问题
2019/01/20 Python
python opencv 检测移动物体并截图保存实例
2020/03/10 Python
美国销售第一的智能手机和平板电脑保护壳:OtterBox
2017/12/21 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
工程质量承诺书
2014/03/27 职场文书
环保小标语
2014/06/13 职场文书
服务明星事迹材料
2014/12/29 职场文书
乡镇团委工作总结2015
2015/05/26 职场文书
2015年小学生暑假总结
2015/07/13 职场文书
2015年圣诞节寄语
2015/08/17 职场文书