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 spac开发者_StackOverflow社区e.
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.
interesting. another evidence that finalize()
should not be used.
it's not your fault and there's not much you can do about it.
maybe try to convince JRuby team to drop finalize()
? shouldn't JRuby take care of resource deallocation at the earliest time instead of waiting till GC? Developers using JRuby are not interfacing with these objects, they are all under the control of JRuby.
精彩评论