Paul, this looks just like the leak that's been fixed. It's all the stuff
getting stuck in the ThreadLocal.

Augustin, have you tried this with the latest build of Jelly?

Hans 

-----Original Message-----
From: Paul Libbrecht [mailto:[EMAIL PROTECTED] 
Sent: Saturday, March 19, 2005 5:38 PM
To: Jakarta Commons Developers List
Subject: Re: [Jelly] Memory leak revealed

Agustin,

I've been trying to reproduce your error, which may be believable I  
fear. I tried to make it simpler, as you described, ... and I did not  
manage it...

Also, you seem to be running a code that calls jelly that calls the  
code again which seems much compared to what you describe.
The growth of the objects seems to be linearly following the growth of  
the number of TagScript objects which means, I think, that a script  
gets reparsed several times... (TagScript objects, as far as I know,  
are only created at compilation time).

Your example is slightly too complicated to my taste since I would need  
a profiler to see it at work...
Differently said... where are these amount of JellyContext objects  
actually created ? Can you give a stacktrace?

thanks for your help !
We are aware of a leak around and would love to see this fixed at some  
point...

paul

Le 19 mars 05, à 04:53, Agustin Ramos a écrit :

> 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$Express 
> ionSupportLocal";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$Express 
> ionSupportLocal";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: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>


---------------------------------------------------------------------
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