[jdom-interest] Bug: SAXBuilder locks last parsed document in memory
Laurent Bihanic
laurent.bihanic at atosorigin.com
Mon Nov 21 15:23:05 PST 2005
Hi,
For one of our applications, we reuse SAXBuilder instances (as a thread-local
variable) with the reuseParser flag set.
When analysing the memory after a traffic peak, we realized that a lot of
memory was never garbage-collected: the last parsed JDOM document for each
application server worker thread.
This is a side effect of reusing the SAXBuilder object : SAXBuilder registers
a SAXHandler object as ContentHandler to the parser and SAXHandler keeps a
reference to the being-built document. When the parse is done, SAXBuilder
retrieves the built document to return it to the user.
But SAXBuilder keeps a reference to the parser which in turn keeps a reference
to the ContentHandler (SAXHandler) which keeps a reference to the document.
The document won't be available for garbage collection until the next parse
begins.
Attached is a patch proposal to add a method clear() to SAXHandler to reset
all references it holds after the parse is complete.
Note: SAXBuilder can't reset the parser's ContentHandler, as setting the
ContentHandler to null is not allowed by SAX.
Laurent
-------------- next part --------------
*** /java/lib/xml/tools/jdom-1.0/src/java/org/jdom/input/SAXBuilder.java 2004-09-03 20:24:28.000000000 +0200
--- SAXBuilder.java 2005-11-12 23:34:49.000000000 +0100
***************
*** 477,482 ****
--- 477,483 ----
// Explicitly nullify the handler to encourage GC
// It's a stack var so this shouldn't be necessary, but it
// seems to help on some JVMs
+ contentHandler.clear();
contentHandler = null;
}
}
-------------- next part --------------
*** /java/lib/xml/tools/jdom-1.0/src/java/org/jdom/input/SAXHandler.java 2004-08-31 08:14:05.000000000 +0200
--- SAXHandler.java 2005-11-12 23:32:08.000000000 +0100
***************
*** 977,980 ****
--- 977,1004 ----
public Locator getDocumentLocator() {
return locator;
}
+
+ /**
+ * Releases all references held by this handler, to make then
+ * available for garbage collection even if the SAX parser
+ * continues keeping a reference to the handler (as the
+ * ContentHandler can not be reset according to the SAX
+ * specification).
+ */
+ public void clear() {
+ // Clear parsed document and factory references.
+ document = null;;
+ currentElement = null;;
+ factory = null;
+
+ // Clear temporary storage.
+ internalSubset = null;
+ textBuffer = null;
+ locator = null;
+
+ declaredNamespaces.clear();
+ declaredNamespaces = null;
+ externalEntities.clear();
+ externalEntities = null;
+ }
}
More information about the jdom-interest
mailing list