This is one of the bugs that's been fixed by the last memory patch.

-----Original Message-----
From: Agustin Ramos [mailto:[EMAIL PROTECTED] 
Sent: Friday, March 18, 2005 10:54 PM
To: Jakarta Commons Developers List
Subject: [Jelly] Memory leak revealed

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$ExpressionSu
pportLocal";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$ExpressionSu
pportLocal";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";17
6
"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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to