You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2002/10/04 19:29:10 UTC

DO NOT REPLY [Bug 13303] New: - Memory leak in XPathContext.popRTFContext()

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: xalan-dev@xml.apache.org
        ReportedBy: rusch@willardrusch.com


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>