This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Path from RaveRenderedDocument -> RaveText: RaveRenderedDocument.userData -> Hashtable.Entry.key -> org.apache.xerces.dom.AttributeMap.nodes -> AbstractRaveDocument.Fix105085AttrImpl.value -> RaveText Path from RaveRenderedDocument -> RaveElement RaveRenderedDocument.userData -> Hashtable.Entry.key -> RaveElement To reproduce: 1) Create a vw project 2) Add a large number of components to the page 3) Switch to JSP view 4) Make a modification 5) Switch to Design view 6) Delete all components 7) Switch to JSP view 8) Make a modification 9) Switch to Design view Steps 3-5 and 7-9 may need to be executed multiple times before the memory leak occurs.
Yes, there needs to be replaced usages of userData, they leak in the apache Document implementation.
First part of the fix, removed usage of userData in WebForm. Checking in visualweb/designer/src/org/netbeans/modules/visualweb/designer/WebForm.java; /cvs/visualweb/designer/src/org/netbeans/modules/visualweb/designer/WebForm.java,v <-- WebForm.java new revision: 1.185; previous revision: 1.184 done
Another part: Checking in visualweb/designer/markup/src/org/netbeans/modules/visualweb/designer/markup/MarkupServiceImpl.java; /cvs/visualweb/designer/markup/src/org/netbeans/modules/visualweb/designer/markup/MarkupServiceImpl.java,v <-- MarkupServiceImpl.java new revision: 1.17; previous revision: 1.16 done
Checking in visualweb/designer/markup/src/org/netbeans/modules/visualweb/designer/markup/MarkupServiceImpl.java; /cvs/visualweb/designer/markup/src/org/netbeans/modules/visualweb/designer/markup/MarkupServiceImpl.java,v <-- MarkupServiceImpl.java new revision: 1.18; previous revision: 1.17 done
Checking in visualweb/designer/markup/src/org/netbeans/modules/visualweb/designer/markup/MarkupServiceImpl.java; /cvs/visualweb/designer/markup/src/org/netbeans/modules/visualweb/designer/markup/MarkupServiceImpl.java,v <-- MarkupServiceImpl.java new revision: 1.19; previous revision: 1.18 done
Fixing in insync module. Checking in visualweb/insync/src/org/netbeans/modules/visualweb/insync/faces/FacesPageUnit.java; /cvs/visualweb/insync/src/org/netbeans/modules/visualweb/insync/faces/FacesPageUnit.java,v <-- FacesPageUnit.java new revision: 1.18; previous revision: 1.17 done Checking in visualweb/insync/src/org/netbeans/modules/visualweb/insync/markup/MarkupUnit.java; /cvs/visualweb/insync/src/org/netbeans/modules/visualweb/insync/markup/MarkupUnit.java,v <-- MarkupUnit.java new revision: 1.11; previous revision: 1.10 done
Last case found, fixed. Checking in visualweb/designer/cssengine/src/org/netbeans/modules/visualweb/designer/cssengine/CssEngineServiceImpl.java; /cvs/visualweb/designer/cssengine/src/org/netbeans/modules/visualweb/designer/cssengine/CssEngineServiceImpl.java,v <-- CssEngineServiceImpl.java new revision: 1.19; previous revision: 1.18 done Now, there shouldn't be userData used anymore (from our modules). Please, check whether those weak hash maps are enough now, or whether there is needed to change to mapping to some weak refs (within those maps).
The WeakHashMap entries do not appear to get cleared when running the test case from the issue description. There are probably strong references from the WeakHashMap values to the keys (which are not visible in a heap dump).
Please, provide, which WeakHashMap instances you refer to.
Some of the maps that I have seen leaking are: - CssEngineServiceImpl.doc2engine (which leaks RaveSourceDocument objects) - MarkupServiceImpl.element2cssStylableElement
First fixed the MarkupServiceImpl.element2cssStylableElement weak hash map. The other one CssEngineServiceImpl.doc2engine is a bit harder, because the map also serves as a holder of the engine. I need to change the references to document from the engine impl (Batik code).
Fixed. Now also the mapping document to css engine should work. Checking in visualweb/designer/cssengine/src/org/netbeans/modules/visualweb/designer/cssengine/CssEngineServiceImpl.java; /cvs/visualweb/designer/cssengine/src/org/netbeans/modules/visualweb/designer/cssengine/CssEngineServiceImpl.java,v <-- CssEngineServiceImpl.java new revision: 1.20; previous revision: 1.19 done
One of the other WeakHashMap instances is causing a memory leak as well: [#document: null]: private static final java.util.Map org.netbeans.modules.visualweb.designer.cssengine.CssEngineServiceImpl.engineKey2engine-> java.util.WeakHashMap@62b644-table-> [Ljava.util.WeakHashMap$Entry;@41502d-[8]-> java.util.WeakHashMap$Entry@1069d5-value-> org.netbeans.modules.visualweb.designer.cssengine.XhtmlCssEngine@81d3f4-document-> org.netbeans.modules.visualweb.designer.markup.RaveSourceDocument@ff1f43
That shoud not be correct. The engine doesn't contain ref to engineKey (so the weak hash map can hold it if the engine key is free). The engineKey is held by the document (via weak hash map again). I.e. somebody else need to hold on the document. Please, provide steps to reproduce, those are missing here.
The steps to reproduce are the same as in the original issue description on the top. From the profiling tools (heapwalker, etc.), the WeakHashMap entries are not deallocated.
Hm, might be that chaining of those weak hash maps doesn't help. I need to check that. If it is so, than some other kind of hack will be needed.
OK, I just checked, it seems that the chaining of the weak hash maps don't work. Thinking about how to by pass the issue.
Fixed. Switched back to userData to keep link between document and css engine. It seems that the userData work OK when used on the document instance (in contrast to the elements). Checking in visualweb/designer/cssengine/src/org/netbeans/modules/visualweb/designer/cssengine/CssEngineServiceImpl.java; /cvs/visualweb/designer/cssengine/src/org/netbeans/modules/visualweb/designer/cssengine/CssEngineServiceImpl.java,v <-- CssEngineServiceImpl.java new revision: 1.21; previous revision: 1.20 done
The current fixes appear to work correctly. However, I see another leak (with the same steps to reproduce) from the RaveRenderedDocument.eventListeners field. The reference graph is approximately: RaveRenderedDocument.eventListeners -> Hashtable.entry.value -> Vector.elementData -> org.apache.xerces.dom.DocumentImpl$LEntry.listener-> org.apache.batik.css.engine.CSSEngine$DOMAttrModifiedListener.this$0 -> XhtmlCssEngine.styleSheetNodes -> RenderedStylesheetLinkElement.ownerNode -> RaveElement.nextSibling -> RaveText
It means those event listeners are the Batik ones (in CSSEngine class). Will look at, what is possible to be done with them.
Ideally there would be a weak listener needed. But there are issues (Batik not dependent on NB, also Dom listener doesn't follow the rules, it doesn't extend java.util.EventListener).
Quy, I was thinking about this, and there shouldn't be a leak caused by this listener, if nobody holds the document, this listener won't cause it to be kept, because the css engine should also get garbaged (it should be held only by the document itself). Also your example points to the RaveRenderedDocument (not source), which there ought to be 1 instance of it, and that is correct, right? Or did you try to point to something else?
There is only one RaveRenderedDocument object, but that is correct if the page is still open. The issue here is that there is a leak of RaveText objects when repeatedly making modifications to a single page by adding components and then deleting them. After a series of modifications, the page returns to its original state (empty), but there are more RaveText objects in memory. This should be easily testable since probes for RaveText are already in place, so you can see the number of live instances in the runtime watches window.
OK, then it needs to be freed the RaveText, but that is not caused by the listener, as long as there is still the same css engine instance. So the steps are to add the text nodes, and remove them? Right?
I do the following: 1) Add a button component 2) Switch to JSP 3) Make a modification 4) Switch back to designer 5) Delete the button Doing these steps repeatedly causes a memory leak that can be seen in the runtime watches window (under 'Important Instances'). The 'find refs' action on any of the probed visual web objects should show you gc roots.
OK, I had a look at it, the path is as you say, but the problem is not in the listener, that one should still be present. But it seems to me in that CssEngine.styleSheetNodes field, it keeps nodes, which are also supposed to be deleted. Looking into it.
Fixed the leak in CSSEngine.styleSheetNodes. Now there wasn't left the button element (for that case). Checking in visualweb/ravelibs/batik/library/nbproject/build-impl.xml; /cvs/visualweb/ravelibs/batik/library/nbproject/build-impl.xml,v <-- build-impl.xml new revision: 1.5; previous revision: 1.4 done Checking in visualweb/ravelibs/batik/library/nbproject/genfiles.properties; /cvs/visualweb/ravelibs/batik/library/nbproject/genfiles.properties,v <-- genfiles.properties new revision: 1.5; previous revision: 1.4 done Checking in visualweb/ravelibs/batik/library/nbproject/project.properties; /cvs/visualweb/ravelibs/batik/library/nbproject/project.properties,v <-- project.properties new revision: 1.4; previous revision: 1.3 done Checking in visualweb/ravelibs/batik/library/src/org/apache/batik/css/engine/CSSEngine.java; /cvs/visualweb/ravelibs/batik/library/src/org/apache/batik/css/engine/CSSEngine.java,v <-- CSSEngine.java new revision: 1.2; previous revision: 1.1 done Checking in visualweb/ravelibs/batik/nbproject/project.properties; /cvs/visualweb/ravelibs/batik/nbproject/project.properties,v <-- project.properties new revision: 1.4; previous revision: 1.3 done