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


    普通的引用变量的销毁大家都知道, 当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

  • 相关阅读:
    新 DAO 访问接口
    TCP/IP协议中的参数说明
    最近在制作一套ASP.NET控件,已初见雏形
    Creating a Dynamic UI with Knockout.js
    数据库性能优化数据库等待队列
    webpy框架
    .Net Web Http状态异常
    一步一步搭架子(完结篇)
    使用yshow分析前端页面性能
    代码混淆、加密
  • 原文地址:https://www.cnblogs.com/sailrancho/p/3394706.html
Copyright © 2020-2023  润新知