PHP闭包对象是否可以进行垃圾回收?

4

我想知道PHP的匿名函数是否可以进行垃圾回收?

我知道使用create_function创建的函数不能进行垃圾回收,但是我没有找到任何关于使用function(){}语法(在内部表示为Closure对象)创建的函数的参考资料。

2个回答

10

PHP 的垃圾回收器不区分“事物”的类型——只要它在某个地方有至少一个引用,它就会被保留。一旦这个条件不再满足,资源就会被垃圾回收。

这与使用 create_function 不同,因为 PHP 在全局范围内引用了 create_function。闭包(如果您愿意,也可以称之为 Closure 对象,因为这就是它们的本质!)仅存在于创建它的作用域和您传递给它的所有作用域中。

如果您想自己验证,请运行以下代码:

<?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();
}

你将只会获得一个回音。将$k分配更改为create_function,您将获得100个回音。


良好的描述。因为它是一个对象,所以我认为它必须超出范围,PHP会做正确的事情。 - Orangepill
@Orangepill: PHP很遗憾并不总是做正确的事情。重点在于,create_function = eval - Sébastien Renauld
我目前正在寻找一种方法来取消在我的项目中使用create_function,但我没有看到任何绕过它的方法。如果您能提供任何指导,将不胜感激。http://codereview.stackexchange.com/questions/26268/potential-problems-with-this-templating-technique - Orangepill
1
顺便说一下,你不应该这样做。这会使PHP远程代码执行变得微不足道。 - Sébastien Renauld
相反,模板可能非常简单,模板处理器试图解决的是 I/O 受限服务器上的迭代文件系统访问。该模板不会用于页面,而是用于表中的行,该表将被包括 1000 次。初始性能测试运行速度比包含快了7.5倍,并且内存消耗几乎减半。 - Orangepill
显示剩余4条评论

0

脱离主题和错误的推理:在除了最简单的情况之外,建议的方法可能会导致错误的推断。测试用例中的内存泄漏将导致错误的结论。 - Sébastien Renauld

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接