DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13303>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13303 Memory leak in XPathContext.popRTFContext() Summary: Memory leak in XPathContext.popRTFContext() Product: XalanJ2 Version: 2.4 Platform: All OS/Version: Solaris Status: NEW Severity: Major Priority: Other Component: org.apache.xpath AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] I'm seeing a memory leak in XPathContext.popRTFContext(). It doesn't look like it's cleaning up the internal m_last_pushed_rtfdtm stack growth from the pushRTFContext() calls . reset() doesn't clean it up either. By my measurement each transform() call increases the size of the internal m_map int[] array by an amount equal to the number of templates "calls" executed. This is an issue for our server app, which caches a transformer and calls transform() many times in a loop. Eventually the app goes into gc thrash. I've got a test case below, and a potential code-fix. I'd appreciate it if someone familiar with the codebase would weigh-in and let me know if the fix makes sense. I think this problem happens only if the stylesheet has RTF constructs. Thanks, --Will Rusch Fix, make popRTFContext symmetric with pushRTFContext() ... < public void popRTFContext() < { > if(null==m_rtfdtm_stack) < return; < int previous=m_last_pushed_rtfdtm.pop(); -- > public void popRTFContext() > { > int previous=m_last_pushed_rtfdtm.pop(); > if(null==m_rtfdtm_stack) > return; Test case: run this and monitor vm resident size, or put print statements in XPathContext to dump the size of the m_last_pushed_rtfdtm stack. import javax.xml.transform.*; import javax.xml.transform.stream.*; import java.io.*; public class foo { public static void main(String[] args) throws TransformerException, TransformerConfigurationException, FileNotFoundException, IOException { Transformer transformer = TransformerFactory.newInstance() .newTransformer (new StreamSource("foo.xsl")); int i=0; while (true) { transformer.transform (new StreamSource("foo.xml"), new StreamResult(new FileOutputStream("foo.out"))); if (++i % 1000 == 0) System.out.println("finished " + i + " transforms"); } } } foo.xsl: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/doc"> <xsl:variable name="x">result tree fragment</xsl:variable> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> <xsl:call-template name="t"/> </xsl:template> <xsl:template name="t"><someoutput/></xsl:template> </xsl:stylesheet> foo.xml: <?xml version="1.0"?> <doc>Hello</doc>
