[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