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

Reply via email to