Req #60087 [NEW]: release() function and __release() method
| From: | luke at cywh dot com | Date: | Tue, 18 Oct 2011 19:39:31 +0000 |
| Subject: | Req #60087 [NEW]: release() function and __release() method | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-164408@lists.php.net to get a copy of this message | ||
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