RE: [PHP-DEV] Re: [RFC] Magic Method that handles unset($object)

From: Date: Sun, 10 Dec 2006 23:16:08 +0000
Subject: RE: [PHP-DEV] Re: [RFC] Magic Method that handles unset($object)
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-26892@lists.php.net to get a copy of this message
Hi, I tried to bring up this subject a view days ago, but without much success. Very good that it's brought up again. Meanwhile I thought about the problem myself. Another way to solve this problem is to look for circular references upon unset. This might be bad for performance, but I believe that preventing a memory leak is something that is the responsibility of PHP, not of the user. ---- The unset() statement could do something like the following (pseudo code): void unset(object) { object->refcount--; list = new Linked_List(); // Linked list with counter for each item count_references(list, object); foreach (list->items as item) { if (item->count != item->object->refcount) return; } foreach (list->items as item) { destroy(item->object); } } void count_references(list, object) { if (list->has_object(object)) { list->inc_count(object); return; } list->add(object); foreach (object->children as child) { count_references(list, child); } } ----- It's important that when an object is destroyed because refcount is 0, unset() is called for all it's children. Also when a variable is unset because of leaving the call stack, unset() should be used. When destoy() is called, it is not necessary to call unset() this. ----- Imagine the following situation: $x --> A --------> B --> C <--> D $y -| | ^ | ->F <-> G | |-> E <-- $z | | -------------| $% is a reference within global or static space or within the call stack. //--- Example 1 --- unset($x); // Would simply lower the refcount of A unset($y); // Would destroy A, F and G, but not the rest unset($z); // Would destroy the rest (B, C, D and E) //--- Example 2 --- unset($z); // Would simply lower the refcount of E unset($x); // Would simply lower the refcount of A unset($y); // Would destroy everything ----- I don't think writing a magic unset method will do the trick, because would cause a problem if you would do: $a = new MyClass(); $b = $a; unset($b); Also when refcount is lowered because of leaving the call stack, calling unset would cause a problem. Not calling unset would still cause the memory leak. I've I'm correct, the method should work in all situations. Best regards, Arnold Daniels Javeline - Create what's next. http://www.javeline.net -----Original Message----- From: news [mailto:news@sea.gmane.org] On Behalf Of Sebastian Bergmann Sent: zondag 10 december 2006 17:26 To: internals@lists.php.net Subject: Re: [PHP-DEV] Re: [RFC] Magic Method that handles unset($object) Sara Golemon wrote: > To do this >right< you'd need notification, not just that unset() was > called on the object, but what the current state of *both* of its > relevant reference counts are. I fail to see why. If we introduce a method that is called for unset() then there should be no problem with resetting the $children attribute to array() in my example: unset($parent) -> "magic method" -> $children = array() -> no references to $child objects Nothing would happen in the case that you describe where other references to the $child objects exist, of course. -- Sebastian Bergmann http://sebastian-bergmann.de/ GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php

« previous php.internals (#26892) next »