5

如果我使用类似于下面代码的节点树结构,我是否需要担心循环引用?
我读过 PHP 使用了一种内存分配机制,当涉及到循环引用时,这会使垃圾收集器的生活变得非常困难。

我想知道的是:

  • 如果我的树只包含几个节点,比如 25 个,这是一个问题吗?
  • 内存会在脚本结束时被释放,还是我慢慢地给服务器造成了问题?
  • 在什么情况下这个问题会在脚本执行过程中产生影响?
  • 手动销毁引用会解决问题吗?我应该总是这样做吗?
class Node {
    private $parent;
    private $children;

    function addChild( Node $child ) {
        $this->children[] = $child;
        $child->setParent( $this );
    }

    function setParent( $parent ) {
        $this->parent = $parent;
    }
}

//eg
$node0 = new Node;
$node1 = new Node;

// nodes 1 and 2 have a circular reference to each other
$node0->addChild( $node1 );
4

4 回答 4

4

逐点:

  • 如果我的树只包含几个节点,比如 25 个,这是一个问题吗?

除非你的节点是真正的怪物。

  • 内存会在脚本结束时被释放,还是我慢慢地给服务器造成了问题?

当解释器关闭时,所有内存都会被释放。

  • 在什么情况下这个问题会在脚本执行过程中产生影响?

我怀疑除非你有非常低的内存限制或非常大的动态数据结构,否则你会担心什么。如果您有 25 个不经常创建/释放的节点,您将不会遇到问题。

  • 手动销毁引用会解决问题吗?我应该总是这样做吗?

我会帮你的。当使用 Propel 将大型数据集加载到我们的数据库中时,我们遇到了很多内存消耗问题,我们跟踪到循环引用没有被释放。我们的解决方案是调用一个清除所有引用的方法。

于 2009-02-09T22:21:14.157 回答
3

也许是这样,但由于它在每个请求结束时都会抛出所有对象(除非你正在缓存),我认为许多 PHP 程序员不会担心这一点。

如果您正在用 PHP 编写命令行脚本,那么也许您有理由担心它,但是您必须编写一些相当复杂的 PHP 代码,然后它才会成为值得担心的事情。如果是这样的话,你会有更大的问题。

祝你好运。

于 2009-02-09T22:00:49.680 回答
3

PHP 5.3 将包括循环引用检测和销毁功能。这是一个可选设置,只应在必要时使用,因为垃圾收集器会影响性能,但它是为您的示例量身定制的。

现在开发,注意在 __destruct() 方法中显式取消引用,并尽可能升级到 5.3。

于 2009-02-09T22:53:19.290 回答
2

鉴于大多数 PHP 页面的性质——也就是说,该进程为网页运行并在完成时被丢弃——我相当怀疑这是一个问题。我以前没有见过循环引用的问题,并且没有问题地使用它们。以我的经验,你会遇到更多的内存消耗问题,但 PHP 5 已经通过从复制对象和数组转移到一定程度上缓解了这一问题,除非另有说明。

于 2009-02-09T22:04:10.080 回答