2012-01-12 4 views
11

Я знаю, что эта проблема существует не менее 3-х лет (Issue 92), но меня все еще не удовлетворяет текущее состояние. Я также знаю, что это не влияет на Tomcat, если вы перезагружаетесь после перераспределения (как указано в Guice + Tomcat potential memory leak).Guice 3.0 + Tomcat 7.0 = утечка памяти ClassLoader

Моя проблема в том, что я испытываю ошибки OutOfMemoryError: PermGen после некоторых перераспределений. Обратите внимание, что я не использую сборники google явно, я использую только Guice 3.0 (через maven). После анализа дампов кучи, я все еще вижу, что поток com.google.inject.internal.Finalizer по-прежнему активен, содержит ссылку на Tomcat WebappClassLoader, что препятствует сбору мусора.

Что делать, если я действительно требует перераспределения без перезапуска и использую Guice? Какие у меня варианты?

ответ

9

Ну, никто не был там, чтобы помочь мне, так вот что я узнал:

Нить Финалайзер запускается FinalizableReferenceQueue (FRQ). Существует жесткая (статическая) ссылка на FRQ в MapMaker. 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); 

Вот обижая код (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(); 
} 

После этого, поток Финалайзер грациозно умирает.

+0

Вот отчет об ошибке по этой проблеме: http://code.google.com/p/google-guice/issues/detail?id=288 – Gili

Смежные вопросы