zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/sailrancho/p/3394706.html
Copyright © 2011-2022 走看看