Janino and Code Cache OutOfMemoryError

View: New views
1 Messages — Rating Filter:   Alert me  

Janino and Code Cache OutOfMemoryError

by Paul Nolan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I have a ituation where I am running some code inside our home grown application server. This code uses Janino to generate code on the fly using the ClassBodyEvaluator and, to a lesser extend, the SimpleCompiler. This code is not executed in any way - we compile the code to "test" rules input by users into our system to make sure that the rules are correct.

First I should say that permGen space is *not* filling up, just the code cache. I am seeing a situation where the code cache is filling up. Now, my understanding of this is that the reason the code cache is filling up is due to some reference to the class compiled by ClassBodyEvaluator is still hanging around in the system. However, my confusion is this: If this is the case then surely the permGen space should alse fill up (or possibly it does so at a much smaller pace than the code cache since it stores meta data only?).

I have passed a custom class loader into the ClassBodyEvaluator to see if this solves the issue but it does not e.g.

            ClassBodyEvaluator cbe = new ClassBodyEvaluator();
            cbe.setParentClassLoader(RVClassLoaderFactory.getRVClassLoader());
            cbe.cook(code);

In my testing code, I nullify my custom class loader when I am finished with it but the code cache still grows and does not get garbage collected. Using JDK 6.

I have used jmap and jhat to try and see what is referencing my class, the following information is from a jmap dump:

      1. ClassLoader for my generated class: org.codehaus.janino.ByteArrayClassLoader@0x1af0f9f0 (54 bytes) (note: not my custom classLoader I pass in above).

      2. In my investiagations using jmap, the finger consistently points at org.codehaus.janino.ByteArrayClassLoader@0x1af0f9f0, even though I pass in a custom class loader above when I am generating the code.

Now, it is well possible that my understanding of how Janino uses classLoaders is limited or how classLoaders work, so if so apologies.

My general question is can someone enlighten me as to the best way to ensure that my code cache does not fill up? Is it as simple as calling Thread.currentThread().setContextClassLoader() ?

regards,

- Paul.