Community
Participate
Working Groups
CSSSWTEngineImpl stores too many element contexts. In a memory snapshot, the HashMap size was 15559. This is most probably a leak.
The class CSSSWTEngineImpl doesn't have any fields - how can it leak memory?
Good question. Don't believe what your profiler is telling you ;-). The 'elementsContext' field is in the super class AbstractCSSEngine. CSSSWTEngineImpl was the actual class used, but the leak may be in any of the super classes.
I think I have found the bug. Open the Call Hierarchy on AbstractCSSEngine.getElementsContext(). There are only two methods where getElementsContext() is called. Method AbstractCSSEngine.getElement(...) is the only place where elements are put into the context. However, there is no place in the code where elements are removed from the context. The context seems to be an ever growing collection of widgets and child element contexts. However, since there was not a large number of widgets in the snapshot, it seems to me as if the elements context is creating child contexts containing the same widgets.
Bogdan, this one is for you :-)
(In reply to comment #4) > Bogdan, this one is for you :-) Hi, The Map elementsContext store the CSS element context for each widget. The Map is never clear but if you see the method AbstractCSSEngine#dispose(), it is setted to null : public void dispose() { reset(); // Call dispose for each CSSStylableElement which was registered Collection contexts = elementsContext.values(); for (Iterator iterator = contexts.iterator(); iterator.hasNext();) { CSSElementContext context = (CSSElementContext) iterator.next(); Element element = context.getElement(); if (element instanceof CSSStylableElement) { ((CSSStylableElement) element).dispose(); } } elementsContext = null; if (resourcesRegistry != null) resourcesRegistry.dispose(); } } Regards Angelo
Created attachment 173826 [details] Patch This patch hooks a widget when an element context is created and stored in the internal map. When a widget is disposed, the element context will be removed. This patch has been tested. Previously, switching the perspective 50 times resulted in a leak of 6 MB. This leak has gone.
Bogdan, any reason why we wouldn't apply this patch?
I have applied the patch. We need to get this into RC2 so that we all run with the changes for long enough to make sure everything still works. If we find problems we can always revert, we have the patch on the bug.
Comment on attachment 173826 [details] Patch Thank you for the patch, Stefan!
I should perhaps not be commenting on an old bug, but I don't believe this was correctly resolved. I am currently experiencing issues with the AbstractCSSEngine leaking memory. The dispose listener for Widgets only had the effect of preventing Widgets from leaking when disposed, but all other data types that end up in the elementsContext map are never removed from the map when they go out of scope but the engine remains in scope. I believe we should be using a WeakHashMap<Object, CSSStylableElement> instead. I am seeing this leak as a fairly serious problem because I am using org.eclipse.nebula.widgets.nattable.NatTable. The NatTable implementation eventually gives the CSSSWTEngineImpl a NatTableWrapper which does not extend Widget. The wrapper class is holding into the NatTable and there is a significant amount of data that is still referenced by the NatTable and it's members. I can try to be more aggressive with the NatTable API to try and clear as many references as I can when it is disposed, but at the end of the day, the AbstractCSSEngine will still be holding onto many references that it defintely should not be.
@Mike: can you please open a new bug about that?
(In reply to Mickael Istria from comment #11) > @Mike: can you please open a new bug about that? And then add a link to it here?
New bug created: https://bugs.eclipse.org/bugs/show_bug.cgi?id=561274