cha*_*tle 11 java tomcat memory-leaks guice
我知道这个问题已经存在至少3年(问题92),但我仍然不满意它的当前状态.我也知道如果你在重新部署后重新启动(如Guice + Tomcat潜在的内存泄漏中所建议的那样),这不会影响Tomcat .
我的问题是我OutOfMemoryError: PermGen在重新部署后遇到了错误.请注意,我没有明确使用google-collections,我只使用Guice 3.0(通过maven).在分析堆转储之后,我仍然看到线程com.google.inject.internal.Finalizer仍处于活动状态,保持对Tomcat的WebappClassLoader的引用,从而阻碍了垃圾收集.
如果我实际上需要重新部署而不重新启动并使用Guice,该怎么办?我有什么选择?
好吧,没有人在那里帮助我,所以这就是我所学到的:
Finalizer线程由FinalizableReferenceQueue(FRQ)启动.MapMaker中有一个对FRQ的硬(静态)引用.WebAppClassLoader没有被垃圾收集,因为由于硬引用,MapMaper仍然存在.
以下代码解决了我的问题:
final Class<?> queueHolderClass =
Class.forName("com.google.inject.internal.util.$MapMaker$QueueHolder");
final Field queueField = queueHolderClass.getDeclaredField("queue");
// make MapMaker.QueueHolder.queue accessible
queueField.setAccessible(true);
// remove the final modifier from MapMaker.QueueHolder.queue
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(queueField, queueField.getModifiers() & ~Modifier.FINAL);
// set it to null
queueField.set(null, null);
Run Code Online (Sandbox Code Playgroud)
下面是问题的代码(com.google.inject.internal.util.MapMaker):
/** Wrapper class ensures that queue isn't created until it's used. */
private static class QueueHolder {
static final FinalizableReferenceQueue queue = new FinalizableReferenceQueue();
}
Run Code Online (Sandbox Code Playgroud)
执行此操作后,Finalizer线程优雅地死亡.
| 归档时间: |
|
| 查看次数: |
2167 次 |
| 最近记录: |