If I am using a tree structure of nodes similar to the code below, do I have to worry about the circular reference?
I have read that PHP uses a memory allocation mechanism which can make life very hard for the garbage collector when there are circular references involved.
What I want to know is:
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 );
Point by point:
- If my tree consists of only a few nodes, say 25, is this a problem?
Not unless your nodes are real monsters.
- Will the memory be freed at the end of the script or am I slowly creating a problem for the server?
When the interpreter shuts down all the memory is released.
- Under what circumstances will this problem have an effect during script execution?
I doubt you will have anything to worry about unless you have very low memory limits or very large dynamic data structures. If you have 25 nodes that aren't being created/freed frequently you won't have an issue.
- Will manually destroying the references solve the problem and should I always do it?
It will help. When loading a large data set into our database with Propel we ran into a lot of problem with memory consumption that we tracked to circular references not being freed. Our solution was to call a method that cleared all references.
Maybe so, but since it throws out all objects at the end of every request (unless you're caching), I don't think many PHP programmers worry about this.
If you're writing command line scripts in PHP, then maybe you've got a case for worrying about it, but you'd have to be writing some pretty convoluted PHP code before it becomes something worth worrying about. And if that's the case you have bigger problems.
Good luck.
PHP 5.3 will include circular reference detection and destruction features. It's an optional setting, and it should only be used when necessary because the garbage collector will take a performance hit, but it's tailor made for your example.
Develop now, take precaution to explicitly dereference in a __destruct() method, and upgrade to 5.3 when possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With