2

在 PHP 7.4 中,当循环引用对象中有方法时,我注意到gc_collect_cycles返回的收集循环数始终为零。destructor

class A {
    public function __destruct() {

    }
}
gc_disable();

$a1 = new A;
$a2 = new A;

$a1->ref = $a2;
$a2->ref = $a1;

$a1 = $a2 = NULL;

echo('removed cycles: '.gc_collect_cycles()); // Output: removed cycles: 0

当我删除该__destruct方法时,输出为:

removed cycles: 2

您可以看到这种行为从 PHP 7.4.0beta4开始

这里发生了什么 ?即使禁用了 GC,是否会在析构函数中收集垃圾循环?

4

1 回答 1

3

从 PHP 7.4 开始,初始垃圾回收运行只会对拥有它们的对象调用析构函数,并且对象的实际销毁推迟到下一次 GC 运行。如果您对 gc_collect_cycles() 执行两次调用,您可以看到这一点:https ://3v4l.org/0LIVn

这种行为的原因是析构函数可以引入对对象的附加引用,这样销毁它就不再有效。以前的版本使用不可靠的启发式来检测这种情况。PHP 7.4 将改为将销毁延迟到单独的 GC 运行。

于 2019-12-10T09:56:10.190 回答