We're running a small JRuby on Rails app under Tomcat 6.0.28 with a Spring-based backend. I've spent some time with the Eclipse Memory Analysis tool and I can definitely tell that instances of the JRubyClassLoader
are leaking. I setup our webapp to only use a single JRuby runtime and then I effectively did a hot-deploy to Tomcat by touching
the war. After doing that a few times, I can see several instances of the JRubyClassLoader
sitting around.
Since the classloader isn't getting released, the classes it loaded aren't getting released and we're running out of PermGen space.
Using Eclipse Memory Analysis, I can see the path to the GC root looks like:
org.jruby.util.JRubyClassLoader
jrubyClassLoader org.jruby.Ruby
runtime org.jruby.util.io.ChannelStream
reference java.lang.ref.Finalizer
next java.lang.ref.Finalizer
And the list of next java.lang.ref.Finalizer
goes on seemingly forever... to point where I can't seem to find the actual GC root.
If run the Leak Suspects report, the #1 suspect is "java.lang.ref.Finalizer", loaded by "<system class loader>".
Any ideas why the Finalizer is sticking around?
EDIT
As a possibly related side note, every time I do a hot deploy, a get a slew of NullPointerExceptions
:
java.lang.NullPointerException
at com.kenai.jffi.Function.finalize(Function.java:177)
at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
EDIT 2
I upgraded to JRuby 1.5.1 and I'm still seeing the same problems.