您的位置:首页 > 编程语言 > PHP开发

PHP GC垃圾回收机制之引用变量回收周期疑问

2013-10-29 17:20 746 查看
普通的引用变量的销毁大家都知道, 当unset的时候如果refcount = 0 则认为无用, 销毁。

但是手册中提到一点会有递归引用的问题,很是奇葩

代码如下

<?php

$a = 1;
$arr[0] = &$a;
$arr[1] = &$arr;
/*
用print_r打印出现
Array
(
[0] => 1
[1] => Array
(
[0] => 1
[1] => Array
*RECURSION*
)

)
*/


这个时候 $arr[1] 递归的引用了$arr , 虽然没有意义,但是按照原来的判断refcount为0的方式会出现问题,因为当unset($arr)时, refcount=1 ,此时$arr成为一个没有任何变量指向的垃圾数据。

手册中提到的方法是

当一个变量出现refcount引用计数减少到非零值时, 这个变量就进去了垃圾回收缓冲区

缓冲区定时进行数据清理

步骤如下

深度优先遍历每个结点,被遍历的结点被标记为已经遍历,第二次遍历到将不会再进行操作, 遍历处理操作是将refcount-- , 如果遍历结束时 refcount=0 则认为是垃圾数据,则回收, 如果refcount>0 则 refcount+=1

此处疑问出来了,这种方式明显有缺陷

比如

1. 对于 $a = 1; $b =&$a; 然后unset($b); 此时$a进入垃圾回收周期, 被遍历,并且refcount--后refcount=0 被回收, 但是$a此时还有用啊。这种情况属于有用的资源被误回收

2. $a = 1; $arr = arrary(); $arr[0] = &$a; $arr[1] = &$arr; $arr[2] = &$arr; unset($arr); 此处有两处引用 , 但是处理的时候如果遍历并且refcount--之后再次遍历不再进行refcount--操作,所以 $arr这种垃圾是没法回收的

官方手册的地址如下, 不知道是不是被我曲解了, http://www.php.net/manual/zh/features.gc.collecting-cycles.php
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: