Java Mailing List Archive

http://www.junlu.com/

Home » Home (12/2007) » JDOM User »

[jdom-interest] Bug: SAXBuilder locks last parsed document in memory

Laurent Bihanic

2005-11-21

Replies:


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
*** /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;
      }
   }
*** /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;
+   }
}
_______________________________________________
To control your jdom-interest membership:
http://www.jdom.org/mailman/options/jdom-interest/youraddr@(protected)
©2008 junlu.com - Jax Systems, LLC, U.S.A.