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.

Reply via email to