例8 把数组作为一个元素添加到本身
- <?php
- $a = array( 'one' );
- $a[] =&$a;
- xdebug_debug_zval( 'a' );
- ?>
以上例程的输出类似于:
图示:

自引用(curcular reference,本身是本身的一个元素)的数组的zval
能看到数组变量 (a) 同时也是这个数组的第二个元素(1) 指向的变量容器中“refcount”为 2。膳绫擎的输出结不雅中的"..."解释产生了递归操作, 显然在这种情况下意味着"..."指向原始数组。
跟方才一样,对一个变量调用unset,将删除这个符号,且它指向的变量容器中的引用次数也减1。所以,如不雅我们在履行完膳绫擎的代码后,对变量$a调用unset, 那么变量 $a 和数组元素 "1" 所指向的变量容器的引用次数减1, 大年夜"2"变成"1". 下例可以解释:
例9 Unsetting $a
- (refcount=1, is_ref=1)=array (
- 0 => (refcount=1, is_ref=0)='one',
- 1 => (refcount=1, is_ref=1)=...
- )
图示:

Zvals after removal of array with a circular reference demonstrating the memory leak
清理变量容器的问题(Cleanup Problems)
尽管不再有某个感化域中的任何符号指向这个构造(就是变量容器),因为数组元素“1”仍然指向数组本身,所以这个容器不克不及被清除 。因为没有别的的符号指向它,用户没有办法清除这个构造,结不雅就会导致内存泄漏。光荣的是,php将裹足本履行停止时清除这个数据构造,然则在php清除之前,将消费不少内存。如不雅你要实现分析算法,或者要做其他像一个子元素指向它的父元素如许的工作,这种情况就会经常产生。当然,同样的情况也会产生在对象上,实际上对象更有可能出现这种情况,因为对象老是隐式的被引用。
- a: (refcount=3, is_ref=0)='new string'
- a: (refcount=1, is_ref=0)='new string'
- <?php
- $a = array( 'meaning' => 'life', 'number' => 42 );
- $a['life'] = $a['meaning'];
- unset( $a['meaning'], $a['number'] );
- xdebug_debug_zval( 'a' );
- ?>
如不雅膳绫擎的情况产生仅仅一两次倒没什么,然则如不雅出现几千次,甚至几十万次的内存泄漏,这显然是个大年夜问题。如许的问题往往产生在长时光运行的脚本中,比如请求根本上不会停止的守护过程(deamons)或者单位测试中的大年夜的套件(sets)中。后者的例子:在给巨大年夜的eZ(一个有名的PHP Library) 组件库的模板组件做单位测试时,就可能会出现问题。有时测试可能须要耗用2GB的内存,而测试办事器很可能没有这么大年夜的内存。
【编辑推荐】
- 自上而下,慢慢揭开PHP解析大年夜整数的面纱
- 基于Swoole的工程级企业微办事框架PHP-MSF宣布3.0.2 版本
- PHPer、Laravel 面试可能碰到的问题及谜底
- PHP7中我们应钙揭捉?习会用的新特点
- ECharts, PHP, MySQL, Ajax, JQuery实现前后端数据可视化
推荐阅读
阿里巴巴发布AliGenie语音开放平台 “智联网”战略又落一子
10月12日消息,在2017杭州•云栖大年夜会上,阿里巴巴人工智能实验室宣布了AliGenie 开放平台,重要包含三大年夜部分:精灵技能市场、硬件开放平台、行业解决筹划,周全赋能智能家居、>>>详细阅读
本文标题:PHP的垃圾回收机制——引用计数
地址:http://www.17bianji.com/lsqh/37855.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示