【问题标题】:Are PHP Closure Objects eligible for garbage collectionPHP 闭包对象是否有资格进行垃圾回收
【发布时间】:2013-05-13 01:25:33
【问题描述】:

我想知道是否有人知道 PHP 的匿名函数是否有资格进行垃圾收集?

我知道使用create_function 创建的函数不会被垃圾回收,但我无法找到有关使用function(){} 语法(内部表示为闭包对象)创建的函数的任何参考。

【问题讨论】:

    标签: php garbage-collection closures


    【解决方案1】:

    可以通过 xdebug_debug_zval( 'a' );如果安装了 xdebug。 http://www.php.net/manual/en/features.gc.refcounting-basics.php

    【讨论】:

    • 离题和错误推理:除了最简单的情况外,建议的方法可能会导致错误的推论。测试用例中的内存泄漏会导致错误的结论。
    【解决方案2】:

    PHP 的垃圾收集器不区分“事物”的类型——如果它在某处至少有一个引用,它就会被保留。当这不适用时,资源将被垃圾收集。

    与使用 create_function 相同,因为 PHP 除了引用它之外,还会在全局范围内抛出 create_function 引用。一个闭包(一个闭包对象,如果你愿意的话,因为它们就是这样!)只存在于它创建的范围内+你传递给它的所有范围内。

    如果你想说服自己,运行这段代码:

    <?php
    $r = memory_get_usage();
    for ($i = 0; $i < 100; $i++) {
        $k = function() {echo "boo"; };
        if (memory_get_usage() > $r) {
                echo "Different memory count. Off by: ".(memory_get_usage() -$r);
        }
        $r = memory_get_usage();
    }
    

    你会得到一个回声。用 create_function 替换 $k 赋值,你会得到 100。

    【讨论】:

    • 很好的描述。因为它是一个对象,我认为它必须超出范围,php 会做正确的事情。
    • @Orangepill:遗憾的是,PHP 并不总是做正确的事。点仍然存在,create_function = eval
    • 我目前正在寻找一种方法来从我正在进行的项目中删除 create_function,但我没有看到任何解决方法。非常感谢您提供codereview.stackexchange.com/questions/26268/… 的任何指导
    • @Orangepill:存储闭包而不是 create_function。当它被调用时,在它之前是 ob_start,在它之后是 ob_get_clean。完成,并且作为一个额外的好处,取消设置部分并且内存也被释放。
    • 顺便说一句,你不应该这样做。它使 PHP 远程代码执行变得微不足道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多