#33595 [Com]: recursive references leak memory
| From: | taneli at crasman dot fi | Date: | Wed, 24 Jan 2007 13:53:46 +0000 |
| Subject: | #33595 [Com]: recursive references leak memory | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-107975@lists.php.net to get a copy of this message | ||
ID: 33595
Comment by: taneli at crasman dot fi
Reported By: rodricg at sellingsource dot com
Status: Assigned
Bug Type: Class/Object related
Operating System: *
PHP Version: 6CVS-2005-08-02
Assigned To: dmitry
New Comment:
It shouldn't be a known "got cha".
I just wrote a backgrounded daemon using PHP and I had to instate a
checker process just to restart the process any time it dies (because
it leaks memory about 30 megs per "daemon loop", because of
references).
Previous Comments:
------------------------------------------------------------------------
[2006-11-02 22:28:05] judas dot iscariote at gmail dot com
taneli at crasman dot fi :
- This is a well known "gotcha" see [1]
- for the gory details, please see [2], this is not "that easy" to
fix.
1.
http://en.wikipedia.org/wiki/Reference_counting#Advantages_and_disadvantages
2. ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps
------------------------------------------------------------------------
[2006-11-01 09:07:48] taneli at crasman dot fi
Please address this bug, it's very short-sighted to rely on the fact
that memory is freed on shutdown (especially when your either your box
starts trashing or memory_limit kicks in and fails your request because
of a bug in the interpreter).
------------------------------------------------------------------------
[2006-08-15 12:02:00] ruslan dot kyrychuk at gmail dot com
Maybe solutution can be to call destructor every time when new object
is assigned to old reference?
Example:
<?php
class A {
function __construct () {
$this->b = new B($this);
}
function __destruct () {
$this->b->__destruct();
}
}
class B {
function __construct ($parent = NULL) {
$this->parent = $parent;
}
function __destruct () {
unset($this->parent);
}
}
for ($i = 0 ; $i < 1000000 ; $i++) {
$a = new A();
$a->__destruct();
}
echo number_format(memory_get_usage());
?>
$a->__destruct(); can be called automatically because new reference is
created. Then writing correct destructors will solve this issue.
Or maybe I missing something?
------------------------------------------------------------------------
[2006-05-04 14:08:22] frode at coretrek dot com
I worked around this exact problem by using a proxy class with a
destructor that explicitly breaks the cycle; I got the idea from a
perl.com[1] article describing how perl suffers from the same problem.
It's also interesting to note that perl has chosen a different (less
elegant) solution to the problem than python, by introducing weak
references.
[1] http://www.perl.com/pub/a/2002/08/07/proxyobject.html
------------------------------------------------------------------------
[2006-04-13 06:24:02] seufert at gmail dot com
I have been experiencing this problem. Unfortunately i have an
application which relies heavily on a class->driver arrangement where
both the class and the driver class need a reference to each other. I
was wondering if we could have a way of getting an uncounted reference
to the object to pass to the child? So the child would have a reference
to the parent, but it would not be counted, and therefore when all
external references to the parent are removed/unset, the parent will
GC, and then the child will be freed as usual.
Is this a workable solution? Even just a reference count decrement
would work. Not a perfect solution, but it would solve calling
descructors all the time.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/33595
--
Edit this bug report at http://bugs.php.net/?id=33595&edit=1