PHP 循环引用问题的规模有多大?我应该担心它吗?
-
22-08-2019 - |
题
如果我使用类似于下面代码的节点树结构,我是否需要担心循环引用?
我读过,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 );
解决方案
逐点:
- 如果我的树仅包含几个节点(例如 25 个),这是否有问题?
除非你的节点是真正的怪物。
- 脚本结束时内存会被释放还是我会慢慢地给服务器带来问题?
当解释器关闭时,所有内存都会被释放。
- 脚本执行过程中什么情况下会出现这个问题?
我怀疑你不会有什么需要担心的,除非你有非常低的内存限制或非常大的动态数据结构。如果您有 25 个不经常创建/释放的节点,则不会出现问题。
- 手动销毁引用可以解决问题吗?我应该始终这样做吗?
我会帮你的。当使用 Propel 将大型数据集加载到数据库中时,我们遇到了很多内存消耗问题,我们跟踪到循环引用未释放。我们的解决方案是调用一个清除所有引用的方法。
其他提示
也许是这样,但由于它在每个请求结束时都会抛出所有对象(除非您正在缓存),所以我认为许多 PHP 程序员不会担心这一点。
如果您正在用 PHP 编写命令行脚本,那么也许您有理由担心它,但在它变得值得担心之前,您必须编写一些非常复杂的 PHP 代码。如果是这样的话,你就有更大的问题了。
祝你好运。
考虑到大多数 PHP 页面的性质——即进程为网页运行并在完成后被丢弃——我相当怀疑这是一个问题。我以前没有见过循环引用的问题,并且使用它们也没有出现问题。根据我的经验,您会遇到更多仅涉及内存消耗的问题,但 PHP 5 已经通过不再仅复制对象和数组(除非另有说明)而在一定程度上缓解了这一问题。
PHP 5.3 将包含循环引用检测和销毁功能。这是一个可选设置,仅应在必要时使用它,因为垃圾收集器会影响性能,但它是为您的示例量身定制的。
立即开发,采取预防措施在 __destruct() 方法中显式取消引用,并在可能的情况下升级到 5.3。
不隶属于 StackOverflow