commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Agustin Ramos <ara...@ciencias.unam.mx>
Subject [Jelly] Memory leak revealed
Date Sat, 19 Mar 2005 03:53:45 GMT
I've been struggling to find a memory leak in an enterprise app
whose GUI we developed using jelly-swing.

Finally I've been able to make a minimalistic test which demonstrates 
the leak.
The problem is with the define:taglib and  define:tag  tags.
The test shows how repeteadly invoking a tag defined in a taglib increases
dramatically the number of instances of JellyContext and objects 
referencing
the contexts, and this objects get never released.

These are the two snapshots of the object instance before and after 
invoking
repeteadly the scripts. The new instances get never released.

Hope this helps.

 >>>>> before.csv

"Name";"Instance count";"Difference";"Size"
"org.apache.commons.jelly.JellyContext";2;0;80
"org.apache.commons.jelly.TagLibrary$1";1;0;8
"org.apache.commons.jelly.expression.ConstantExpression";15;0;240
"org.apache.commons.jelly.expression.jexl.JexlExpression";3;0;48
"org.apache.commons.jelly.expression.jexl.JexlExpressionFactory";1;0;16
"org.apache.commons.jelly.expression.jexl.JexlExpressionFactory$ExpressionSupportLocal";3;0;72
"org.apache.commons.jelly.impl.CompositeTextScriptBlock";1;0;16
"org.apache.commons.jelly.impl.DefaultTagFactory";11;0;176
"org.apache.commons.jelly.impl.DynamicTagLibrary";1;0;24
"org.apache.commons.jelly.impl.ExpressionScript";1;0;16
"org.apache.commons.jelly.impl.ScriptBlock";12;0;192
"org.apache.commons.jelly.impl.StaticTagScript";1;0;64
"org.apache.commons.jelly.impl.TagScript";11;0;704
"org.apache.commons.jelly.impl.TextScript";5;0;80
"org.apache.commons.jelly.parser.XMLParser";1;0;80
"org.apache.commons.jelly.parser.XMLParser$1";1;0;24
"org.apache.commons.jelly.tags.core.ArgTag$1";1;0;16
"org.apache.commons.jelly.tags.core.ArgTag$2";1;0;16
"org.apache.commons.jelly.tags.core.ArgTag$3";1;0;16
"org.apache.commons.jelly.tags.core.ArgTag$4";1;0;16
"org.apache.commons.jelly.tags.core.ArgTag$5";1;0;16
"org.apache.commons.jelly.tags.core.ArgTag$6";1;0;16
"org.apache.commons.jelly.tags.core.CoreTagLibrary";1;0;16
"org.apache.commons.jelly.tags.core.JellyTag";1;0;32
"org.apache.commons.jelly.tags.define.DefineTagLibrary";1;0;16
"org.apache.commons.jelly.tags.define.ScriptTag";1;0;32
"org.apache.commons.jelly.tags.define.TagTag";1;0;32
"org.apache.commons.jelly.tags.define.TaglibTag";1;0;40
"org.apache.commons.jelly.tags.log.LogTagLibrary";1;0;16

 >>>>. after.csv

"Name";"Instance count";"Difference";"Size"
"org.apache.commons.jelly.expression.ConstantExpression";165;"+150";2,640
"org.apache.commons.jelly.impl.TagScript";131;"+120";8,384
"org.apache.commons.jelly.impl.ScriptBlock";122;"+110";1,952
"org.apache.commons.jelly.impl.DefaultTagFactory";121;"+110";1,936
"org.apache.commons.jelly.expression.jexl.JexlExpressionFactory$ExpressionSupportLocal";33;"+30";792
"org.apache.commons.jelly.JellyContext";32;"+30";1,280
"org.apache.commons.jelly.expression.jexl.JexlExpression";33;"+30";528
"org.apache.commons.jelly.tags.core.InvokeStaticTag";20;"+20";1,120
"org.apache.commons.jelly.tags.core.InvokeTag";20;"+20";1,120
"org.apache.commons.jelly.tags.core.ArgTag";20;"+20";960
"org.apache.commons.jelly.expression.jexl.JexlExpressionFactory";11;"+10";176
"org.apache.commons.jelly.tags.core.JellyTag";11;"+10";352
"org.apache.commons.jelly.tags.define.TaglibTag";11;"+10";440
"org.apache.commons.jelly.tags.define.ScriptTag";11;"+10";352
"org.apache.commons.jelly.impl.DynamicTagLibrary";11;"+10";264
"org.apache.commons.jelly.impl.DynamicTag";10;"+10";400
"org.apache.commons.jelly.tags.define.TagTag";11;"+10";352
"org.apache.commons.jelly.impl.ExpressionScript";11;"+10";176
"org.apache.commons.jelly.impl.TextScript";15;"+10";240
"org.apache.commons.jelly.impl.CompositeTextScriptBlock";11;"+10";176
"org.apache.commons.jelly.impl.DynamicTagLibrary$1";10;"+10";160
"org.apache.commons.jelly.tags.log.DebugTag";10;"+10";400



 >>>>>>>>>>>>>>>   Main.java
package test.jelly;

import java.io.*;
import java.net.*;
import org.apache.commons.jelly.*;

public class Main
{
   private static Main instance;
   private JellyContext context;

   static{
      instance = new Main();
   }

   private Main() {
      context = new JellyContext();
      context.setClassLoader(getClass().getClassLoader());
   }

   public static Main getInstance() {
      return instance;
   }
       
   public JellyContext runScript( String scriptName ) {
    JellyContext childJC = null;

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try {
         URL url = this.getClass().getResource(scriptName);
        String exturl = url.toExternalForm();
        int lastSlash = exturl.lastIndexOf("/");
        String extBase = exturl.substring(0,lastSlash+1);
        URL baseurl = new URL(extBase);
        context.setCurrentURL(baseurl);

        XMLOutput xmlOutput = XMLOutput.createXMLOutput(out);
       childJC = context.runScript( scriptName, xmlOutput);
       xmlOutput.flush();
    } catch (Exception e) {
       e.printStackTrace();
       throw new RuntimeException(e.getMessage());
    }
     finally{
         try{ out.close(); }catch( Exception e ){/*DO NOTHING*/}
         out = null;
     }
    return childJC;
   }

   public void addInt( int integer ) {
      Integer i = (Integer)context.findVariable("integer");
      if( i == null ){
         i = new Integer(0);
         context.setVariable("integer",i);
      }
      i = new Integer( i.intValue() + integer );
      context.setVariable("integer",i);
   }

   public static void main( String[] args ) {
      try {
           int n = Integer.parseInt(args[0]);

         Main main = Main.getInstance();
         main.runScript("definetag.jelly");

            // Read a line to start the test
          System.in.read();

         for (int i=0; i < n; i++) {
            main.runScript("invoketag.jelly");
         } 
           // To take the profiling snapshot
          System.in.read();
      } catch (Exception ex) {
        ex.printStackTrace();
      }
   }
}

 >>>>>>>>>>  definetag.jelly

<?xml version="1.0"  encoding="ISO-8859-1"?>
<j:jelly
    xmlns:j="jelly:core"
    xmlns:log="jelly:log"
    xmlns:define="jelly:define"
    xmlns:bogus="bogus"
   xmlns:swing="jelly:swing">

    <define:taglib uri="bogus">
        <define:tag name="count">
              <j:invokeStatic className="test.jelly.Main" 
method="getInstance" var="main" />
            <j:invoke on="${main}" method="addInt" >
                <j:arg value="1" type="int" />
            </j:invoke>
            <log:debug>bogus ${integer}</log:debug>
        </define:tag>
    </define:taglib> 

    <define:script var="incrCounter">
          <j:invokeStatic className="test.jelly.Main" 
method="getInstance" var="main" />
        <j:invoke on="${main}" method="addInt" >
            <j:arg value="1" type="int" />
        </j:invoke>
       <bogus:count/>
   </define:script>
</j:jelly>

 >>>>>>  invoketag.jelly

<?xml version="1.0"  encoding="ISO-8859-1"?>
<j:jelly
    xmlns:j="jelly:core"
    xmlns:log="jelly:log"
    xmlns:define="jelly:define"
   xmlns:swing="jelly:swing">

   <j:include uri="definetag.jelly" />
   <define:invoke script="${incrCounter}" />
    <log:debug>Count: ${integer}</log:debug>
</j:jelly>




---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message