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