2012-01-12 13 views
11

मुझे पता है कि यह समस्या कम से कम 3 yeears (Issue 92) के आसपास रही है, लेकिन मैं अभी भी इसकी वर्तमान स्थिति से संतुष्ट नहीं हूं। मुझे यह भी पता है कि यदि आप पुनर्वितरण के बाद पुनरारंभ करते हैं तो यह टोमकैट को प्रभावित नहीं करता है (जैसा कि Guice + Tomcat potential memory leak में सुझाया गया है)।गिइस 3.0 + टॉमकैट 7.0 = क्लासलोडर मेमोरी लीक

मेरी समस्या यह है कि मुझे कुछ पुनर्निर्माण के बाद OutOfMemoryError: PermGen त्रुटियों का सामना करना पड़ रहा है। ध्यान दें कि मैं स्पष्ट रूप से Google संग्रह का उपयोग नहीं कर रहा हूं, मैं केवल गुइस 3.0 (मेवेन के माध्यम से) का उपयोग कर रहा हूं। हीप डंप का विश्लेषण करने के बाद, मुझे अभी भी पता है कि com.google.inject.internal.Finalizer धागा अभी भी सक्रिय है, तो टॉमकैट के वेबएप क्लासलोडर का संदर्भ रखता है, इस प्रकार कचरा संग्रह में बाधा डालता है।

क्या होगा यदि मैं वास्तव में पुन: प्रारंभ किए बिना पुन: नियोजन की आवश्यकता है और गुइस का उपयोग कर रहा हूं? मेरे विकल्प क्या हैं?

उत्तर

9

ठीक है, वहां कोई नहीं था मेरी मदद करने के लिए है, तो यहाँ मैं क्या सीखा है:

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

यहाँ हमलावर कोड (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(); 
} 

यह करने के बाद, finalizer धागा शान से मर जाता है।

+0

यहां इस समस्या के लिए बग रिपोर्ट है: http://code.google.com/p/google-guice/issues/detail?id=288 – Gili

संबंधित मुद्दे