From:             
Operating system: 
PHP version:      5.3.8
Package:          Class/Object related
Bug Type:         Feature/Change Request
Bug description:release() function and __release() method

Description:
------------
This is in reference to circular references, as outlined in this bug:

https://bugs.php.net/bug.php?id=33595

The "solution" in PHP 5.3 is the garbage collector, which seems to work
well. 
But it's lazy, meaning it only frees memory when it has to. On a complex
web 
application I came across a situation where the garbage collector didn't
free 
memory like it should have. Eventually the script ran out of memory.
Granted it 
got a lot farther than 5.2 did.

The most common occurrence (only?) of a circular reference is a parent and
child 
relationship with objects. The unset() function is useless because a
reference 
is held, so __destruct is never ran.

I propose an additional more aggressive function called release(). It would

function just like unset(), but would additionally call a __release()
method 
within the object allowing for cleanup before unsetting the object.

If the __release() method doen't exist perhaps PHP could unset the
properties 
itself, and call __release() on any objects that may be stored in an 
array/property.

I've added a demo of how this could work. The demo is different in that it

requires __release(). An internal solution may not.

Test script:
---------------
gc_disable();

interface Release {
        function __release();
}

class A implements Release {
        function __construct() {
                $this->b = new B($this);
        }

        function __release() {
                unset($this->b);
        }
}

function release(Release &$obj) {
        $obj->__release();
        $obj = NULL;
}

class B {
        function __construct($parent = NULL) {
                $this->parent = $parent;
        }
}

for($i = 0; $i < 1000000; $i++) {
    $a = new A();
    release($a);
}



-- 
Edit bug report at https://bugs.php.net/bug.php?id=60087&edit=1
-- 
Try a snapshot (PHP 5.4):            
https://bugs.php.net/fix.php?id=60087&r=trysnapshot54
Try a snapshot (PHP 5.3):            
https://bugs.php.net/fix.php?id=60087&r=trysnapshot53
Try a snapshot (trunk):              
https://bugs.php.net/fix.php?id=60087&r=trysnapshottrunk
Fixed in SVN:                        
https://bugs.php.net/fix.php?id=60087&r=fixed
Fixed in SVN and need be documented: 
https://bugs.php.net/fix.php?id=60087&r=needdocs
Fixed in release:                    
https://bugs.php.net/fix.php?id=60087&r=alreadyfixed
Need backtrace:                      
https://bugs.php.net/fix.php?id=60087&r=needtrace
Need Reproduce Script:               
https://bugs.php.net/fix.php?id=60087&r=needscript
Try newer version:                   
https://bugs.php.net/fix.php?id=60087&r=oldversion
Not developer issue:                 
https://bugs.php.net/fix.php?id=60087&r=support
Expected behavior:                   
https://bugs.php.net/fix.php?id=60087&r=notwrong
Not enough info:                     
https://bugs.php.net/fix.php?id=60087&r=notenoughinfo
Submitted twice:                     
https://bugs.php.net/fix.php?id=60087&r=submittedtwice
register_globals:                    
https://bugs.php.net/fix.php?id=60087&r=globals
PHP 4 support discontinued:          
https://bugs.php.net/fix.php?id=60087&r=php4
Daylight Savings:                    https://bugs.php.net/fix.php?id=60087&r=dst
IIS Stability:                       
https://bugs.php.net/fix.php?id=60087&r=isapi
Install GNU Sed:                     
https://bugs.php.net/fix.php?id=60087&r=gnused
Floating point limitations:          
https://bugs.php.net/fix.php?id=60087&r=float
No Zend Extensions:                  
https://bugs.php.net/fix.php?id=60087&r=nozend
MySQL Configuration Error:           
https://bugs.php.net/fix.php?id=60087&r=mysqlcfg

Reply via email to