>> It got worse (using trunk rev 15905).
>> After 3000 qx.ui.core.Widgets I stopped. Leaked already >50MB.

As nothing seems to have further improved so far, I wrote a small class 
for finding the missing leaks. Actually it just scans the qx-namespace and 
prints all living object (and the first found  reference-path to this 
object).
I will post this class the following days (needs some polishing, currently 
its just hacked together) but as a quick result here is the output which 
shows, that references on 'qx.html.Element' seem to cause the leak, though 
all widget and element instances under test are correctly disposed.

------
ERROR: 1945ms LeakSearcher[hp]: Found disposed but still referenced Obj 
'qx.html.Element' , hash '10', path: 
'qx->Bootstrap->$$registry->qx.core.ObjectRegistry->__registry->2->__context->_modified->10'
-----
Translated it just means, that in the ObjectRegistry an Object with hash 
'2' holds references to disposed qx.html.Elements in its variable 
'__context._modified'.
This message I get for quite a lot already disposed qx.html.Elements.

Object with hash '2' is the following: 
------
INFO: 1948ms LeakSearcher[hp]: Found living Obj 'qx.util.DeferredCall' , 
hash '2', path: 
'qx->Bootstrap->$$registry->qx.core.ObjectRegistry->__registry->2->__context->__deferredCall'
--------

Though maybe not seeable in the first moment, one will find, that the 
'__context' of this 'DeferredCall'-instance points to the statics of 
'qx.html.Element', and thus I conclude the static 
'qx.html.Element._modified' - variable is holding references to disposed 
qx.html.Elements..

I couldn't resist to dig deeper and found a really nasty bug on Element 
disposal, which happens, when Elements are disposed in the wrong order.
Say we have 2 elements: ParentElem und SubElement.  When ParentElement is 
disposed first, a reference to itself stays in the static _modified-map.

The following stacktrace (read from bottom to top) tries to explain this.:

- ParentElem._scheduleChildrenUpdate  <-- puts reference of 
                                          disposed ParentElem 
                                          in _modified Map
- ParentElem.__removeChildHelper
- ParentElem.remove() 
- SubElem.destruct()  <-- child tries to remove itself 
                          from parent, thus calls 'remove' on parent.
- SubElem.dispose()   <-- for each children dispose is called
- ParentElem.disposeArray() 
- ParentElem.destruct()  <- normal destructor call, 
                            calls diposeArray to release children
- ParentElem.dispose()   <- parentElem is disposed somewhen

Actually it looks like that this should be avoided, at least 
__removeChildHelper checks, whether the qx.html.Element._element is set. 
Unfortunataly at this moment the destructor of ParentElement hasn't 
finished yet and _element is still set.

I have some ideas how to solve this, it's your turn to decide on the right 
one :D ...
1) reorder Element disposal to avoid this situation
2) make __removeChildHelper call isDisposed() before scheduling the 
children update and check other places where _element is checked for null.
3) rearrange order in the destructor: call _disposeArray("__children") 
after all other fields (at least _element) are reset. Beware: this might 
prevent correct removal of child-DOM-Nodes (as in 0.7.3). Since at least 
the DOM-Node of ParentElem is removed, this shouldn't be a problem here, 
because the ParentElem is removed and the browser should correctly garbage 
collect all  still connected children-DOM-nodes.
4) On Element.flush() discard disposed references.

As a quick test I chose idea 2+3 and now 20.000 created/destroyed 
Widgets/Labels 'only' leak about 8MB.
As I can't find any wrong Javascript references anymore, I suppose this is 
either the leaking ObjectRegistry or I just disabled correct DOM-node 
removal again ...

As I consider this whole situation as very fragile (even when fixed 
somehow its too easy to introduce the same bug again by chance), I'll put 
some final work in polishing and posting the small leak-finder. 
With that you'll be able to write unit-tests which hopefully automatically 
can test correct disposal of any Qooxdoo-object. 



-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
qooxdoo-devel mailing list
qooxdoo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to