深入解析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和ACCESS写聊天室(七)
Oct 09 PHP
第五节--克隆
Nov 16 PHP
php INI配置文件的解析实现分析
Jan 04 PHP
PHP实现无限级分类(不使用递归)
Oct 22 PHP
详解PHP的Yii框架中扩展的安装与使用
Apr 01 PHP
PHP实现的激活用户注册验证邮箱功能示例
Jun 06 PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 PHP
thinkPHP5框架auth权限控制类与用法示例
Jun 12 PHP
PHP正则判断一个变量是否为正整数的方法
Feb 27 PHP
Yii框架日志操作图文与实例详解
Sep 09 PHP
Laravel实现ApiToken认证请求
Oct 14 PHP
解决PHP Opcache 缓存刷新、代码重载出现无法更新代码的问题
Aug 24 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中RewriteCond规则参数的详细介绍
2013/06/30 PHP
smarty高级特性之过滤器的使用方法
2015/12/25 PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
2017/07/03 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
JavaScript 特殊字符
2007/04/05 Javascript
JavaScipt基本教程之JavaScript语言的基础
2008/01/16 Javascript
Javascript 刷新全集常用代码
2009/11/22 Javascript
利用JQuery的load函数动态加载其它页面的内容的实现代码
2010/12/14 Javascript
JSON语法五大要素图文介绍
2012/12/04 Javascript
解析javascript 浏览器关闭事件
2013/07/08 Javascript
根据表格中的某一列进行排序的javascript代码
2013/11/29 Javascript
JavaScript 学习笔记之变量及其作用域
2015/01/14 Javascript
使用AmplifyJS组件配合JavaScript进行编程的指南
2015/07/28 Javascript
详解maxlength属性在textarea里奇怪的表现
2015/12/27 Javascript
使用纯JS代码判断字符串中有多少汉字的实现方法(超简单实用)
2016/11/12 Javascript
使用node.js搭建服务器
2017/05/20 Javascript
用js实现before和after伪类的样式修改的示例代码
2017/09/07 Javascript
JS中判断某个字符串是否包含另一个字符串的五种方法
2018/05/03 Javascript
vue中使用codemirror的实例详解
2018/11/01 Javascript
Vue实现简单的留言板
2020/10/23 Javascript
python3模拟百度登录并实现百度贴吧签到示例分享(百度贴吧自动签到)
2014/02/24 Python
python实现无证书加密解密实例
2014/10/27 Python
Python实现获取操作系统版本信息方法
2015/04/08 Python
python脚本设置超时机制系统时间的方法
2016/02/21 Python
用Python将结果保存为xlsx的方法
2019/01/28 Python
Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解
2020/02/14 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
Python __slots__的使用方法
2020/11/15 Python
意大利奢侈品购物网站:Giglio
2018/01/05 全球购物
广州品高软件.net笔面试题目
2012/04/18 面试题
大客户销售经理职责
2013/12/04 职场文书
《盲人摸象》教学反思
2014/02/16 职场文书
2014年中秋寄语
2014/08/11 职场文书
幼儿园辞职信
2015/05/13 职场文书
导游词之新疆尼雅遗址
2019/10/16 职场文书
以MySQL5.7为例了解一下执行计划
2022/04/13 MySQL