我们在 Tomcat 6.0.28 下运行一个小型 JRuby on Rails 应用程序,并带有基于 Spring 的后端。我花了一些时间使用 Eclipse 内存分析工具,我可以肯定地说,这些实例JRubyClassLoader
正在泄漏。我将我们的 web 应用程序设置为仅使用一个 JRuby 运行时,然后通过touching
战争有效地对 Tomcat 进行了热部署。这样做几次之后,我可以看到几个JRubyClassLoader
坐在周围的实例。
由于类加载器没有被释放,它加载的类没有被释放,我们的 PermGen 空间已经用完了。
使用 Eclipse 内存分析,我可以看到 GC 根的路径如下所示:
org.jruby.util.JRubyClassLoader
jrubyClassLoader org.jruby.Ruby
runtime org.jruby.util.io.ChannelStream
reference java.lang.ref.Finalizer
next java.lang.ref.Finalizer
而且清单next java.lang.ref.Finalizer
似乎永远在继续……指出我似乎无法找到实际的 GC 根。
如果运行泄漏嫌疑人报告,#1 嫌疑人是“java.lang.ref.Finalizer”,由“<system class loader>”加载。
任何想法为什么终结器仍然存在?
编辑
作为一个可能相关的旁注,每次我进行热部署时,都会获得大量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)
编辑 2
我升级到 JRuby 1.5.1,我仍然看到同样的问题。