PHP 7.4 中的循环引用
Cyclic references in PHP 7.4
在 PHP 7.4 中,我注意到当循环引用对象中有 destructor
方法时,gc_collect_cycles 返回的收集循环数始终为零。
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 被禁用,垃圾循环也会在析构函数中收集吗?
自PHP 7.4 起,初始垃圾收集运行 将只对具有析构函数的对象调用析构函数,对象的实际销毁推迟到下一次GC 运行 .如果对 gc_collect_cycles() 执行两次调用,您可以看到这一点:https://3v4l.org/0LIVn
此行为的原因是析构函数可以引入对该对象的额外引用,这样就不再有效地销毁它。以前的版本使用不可靠的启发式方法来检测这种情况。 PHP 7.4 将改为将销毁延迟到单独的 GC 运行。
在 PHP 7.4 中,我注意到当循环引用对象中有 destructor
方法时,gc_collect_cycles 返回的收集循环数始终为零。
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 被禁用,垃圾循环也会在析构函数中收集吗?
自PHP 7.4 起,初始垃圾收集运行 将只对具有析构函数的对象调用析构函数,对象的实际销毁推迟到下一次GC 运行 .如果对 gc_collect_cycles() 执行两次调用,您可以看到这一点:https://3v4l.org/0LIVn
此行为的原因是析构函数可以引入对该对象的额外引用,这样就不再有效地销毁它。以前的版本使用不可靠的启发式方法来检测这种情况。 PHP 7.4 将改为将销毁延迟到单独的 GC 运行。