2012-01-12 14 views
11

Bu sorunun en az 3 yıl boyunca (Issue 92) olduğunu biliyorum, ancak hala bu durumun mevcut durumundan memnun değilim. Redcat işleminden sonra yeniden başlattığınızda (Guice + Tomcat potential memory leak'da önerildiği gibi) bunun Tomcat'i etkilemediğinin farkındayım.Guice 3.0 + Tomcat 7.0 = ClassLoader bellek sızıntısı

Benim sorunum, bazı yeniden paylaşımlardan sonra OutOfMemoryError: PermGen hataları yaşıyorum. Açıkça google-collections kullanmama dikkat edin, sadece Guice 3.0 kullanıyorum (maven ile). Yığın dökümlerini analiz ettikten sonra, hala com.google.inject.internal.Finalizer iş parçacığının hala aktif olduğunu görüyorum, Tomcat'in WebappClassLoader ürününe bir referans tutar, böylece çöp toplama işlemini engeller.

aslında yeniden başlatmadan yeniden dağıtım gerektiriyorsa ve Guice kullanıyorum? Seçeneklerim nelerdir?

cevap

9

Eh, kimse bana yardım etmek için orada olduğunu, bu yüzden burada öğrendiğim budur:

Finalizer iplik FinalizableReferenceQueue (FRQ) tarafından başlatılır. MapMaker'da FRQ'ye sert (statik) bir referans var. WebAppClassLoader toplanan çöp değildi, çünkü MapMaper sabit referans nedeniyle hala etrafındaydı.

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); 

İşte kusurlu kodu (com.google.inject.internal.util.MapMaker) var:

Aşağıdaki kod

sorunumu çözdü Bunu yaptıktan sonra

/** Wrapper class ensures that queue isn't created until it's used. */ 
private static class QueueHolder { 
    static final FinalizableReferenceQueue queue = new FinalizableReferenceQueue(); 
} 

, Finalizer iplik incelikle ölür.

+0

Bu sorunun hata raporu şöyledir: http://code.google.com/p/google-guice/issues/detail?id=288 – Gili