Hi Andrei,
it seems that there are leftover references to the Script classes
which causes them not to be garbage collected. I've created a patch
that I believe will solve this and logged a JIRA issue[1]

You can test if this helps in your case by modifying the
`GroovyLanguage.java` as in[1] and replacing the resulting class in
the camel-groovy bundle.

I've tested by running an endless loop and seeing if it will stop
OutOfMemoryError:

CamelContext context = new DefaultCamelContext();
Exchange exchange = new DefaultExchange(context, ExchangePattern.InOnly);
while (true) {
    GroovyLanguage.groovy(Math.random() * 10000 + " + " +
Math.random() * 10000).evaluate(exchange);
}

With the stock camel-groovy (I've tested with 2.18.1 and 2.16.6) on
Java 7 and 8 I would get OutOfMemoryError with 64MB heap in about 2-3
minutes, I've run the patched version for 15 minutes without issues.

zoran

[1] https://issues.apache.org/jira/browse/CAMEL-10732
[2] https://github.com/apache/camel/pull/1414/files

On Fri, Jan 20, 2017 at 4:46 PM, artaxerxe <mapand...@gmail.com> wrote:
> As you know, Java isn't getting rid of PermGen memory area until Java 1.8.
> This means that if you are loading a lot of classes using a Java 1.7 JVM
> without assuring they are cleared when no longer needed, you will sooner or
> later get a PermGen OutOfMemory error.
>
> I'm using Camel 2.16.3 inside an OSGI context - Karaf. That means that in my
> situation, camel is started using its OSGI activator. Besides this, my camel
> contexts are built up using Spring context XML DSL.
>
> The problem is that sometimes I get the loathed PermGen OutOfMemory
> exception (after running my OSGI server for a quite long time) so that I
> need to restart it. I took the heap dump on OOM, and I observed that there
> are lots of classes called ScriptXXX where XXX is a number from 1 to about
> 34000. It seems to me that this problem comes from camel+groovy combination.
>
> I found that:
>
> When I run this example:
>                 String scriptText = "request.substring(0, 7)";
>                 Script s = null;
>
>                 GroovyShell shell = new GroovyShell();
>                 Class<Script> sc = 
> shell.getClassLoader().parseClass(scriptText);
>                 s = sc.newInstance();
>                 Map<String, Object> vars = new HashMap<>();
>                 vars.put("request", "after all, that's an example.");
>                 s.setBinding(new Binding(vars));
>                 Object value = s.run();
>                 System.out.println(value);
>                 Thread.sleep(TimeUnit.SECONDS.toMillis(1));
>
> in a for loop, I get lots of classes called somehow like:
> script14849241310141377025920, where the number after "script" is changed
> for each class.
>
> When I run this example:
>        private static void tryOOM(ScriptEngineFactory factory) throws
> ScriptException, InterruptedException {
>
>                 String scriptText = "request.substring(0, 7)";
>
>                 ScriptEngine engine = factory.getScriptEngine();
>                 ScriptContext ctx = engine.getContext();
>                 ctx.setAttribute("request", "aftar all, that's an example.",
> ScriptContext.ENGINE_SCOPE);
>                 engine.eval(scriptText, ctx);
>                 Thread.sleep(TimeUnit.SECONDS.toMillis(1));
>
>         }
> in a for loop, I get lots of classes called like: ScriptXXX, as the ones
> which I found in OOM dump.
>
> Searching in the camel source code, I can see that there are 2 different
> places where groovy scripts are loaded. One way is via ScriptBuilder, which
> is in camel-scripts module, and the other is via camel-groovy module. The
> way which produces ScriptXXX classes is the loading of groovy through
> ScriptBuilder. Anyway, I observe that this is not always true. Sometimes, it
> manages to make it the other way, even if it goes through ScriptBuilder. By
> the "other way" I mean that resulted created classes in groovy are called
> like "scriptXXXXXXXXXXXXXXXXXX..". I tried to reproduce this locally, but it
> gives me different results, which I cannot correlate.
>
> I'm trying to search for the place where groovy scripts are created in order
> to make them candidates for GC when no longer in use.
>
> Can anyone help me/advice what should I do in order to fix this?
>
> Thanks,
> Andrei M.
>
>
>
> --
> View this message in context: 
> http://camel.465427.n5.nabble.com/Groovy-and-Camel-PermGen-troubles-with-Java-1-7-tp5792865.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Zoran Regvart

Reply via email to