2013-10-24 19 views
5

से अधिक हो गई है मैं कक्षाएं उत्पन्न करने और रन टाइम पर उन्हें लोड करने की कोशिश कर रहा हूं।
कक्षाओं को लोड करने के लिए मैं ClassLoader ऑब्जेक्ट का उपयोग कर रहा हूं। चूंकि मैं समय-समय पर PermGen मेमोरी से बाहर नहीं निकलना चाहता हूं, इसलिए मैं कक्षा लोडर का संदर्भ नहीं देता और उपयोग करने के लिए नए वर्गों को लोड करने के लिए एक नया निर्माण करता हूं। यह ठीक काम करता प्रतीत होता है और मुझे स्मृति से PermGen नहीं मिलता है।स्मृति से बाहर PermGen से बचें और जीसी ओवरहेड सीमा

java.lang.OutOfMemoryError: GC overhead limit exceeded 

तो मेरे सवाल है, जब मैं संयुक्त राष्ट्र-संदर्भ वर्ग लोडर दोनों त्रुटियों ?:
मैं पर नजर रखने चाहिए से बचने के लिए चाहिए: समस्या यह है कि जब मुझे लगता है कि, कुछ समय के बाद मैं निम्न त्रुटि मिलता है है मेरे कोड में PermGen उपयोग ताकि मैं कक्षा लोडर को अन-संदर्भित कर सकूं और System.gc() पर कॉल कर सकूं जब PermGen उपयोग सीमा के करीब है?
या मुझे एक अलग दृष्टिकोण का पालन करना चाहिए?
धन्यवाद

उत्तर

6

इसका कोई भी सही जवाब नहीं है।

एक तरफ, यदि क्लासलोडर को अनलिंक करना आपके परमेजन रिसाव की समस्याओं को हल कर रहा है, तो आपको ऐसा करना जारी रखना चाहिए।

दूसरी तरफ, "जीसी ओवरहेड सीमा पार हो गई" त्रुटि का मतलब है कि आपका आवेदन कचरा संग्रह में बहुत अधिक समय व्यतीत कर रहा है। ज्यादातर परिस्थितियों में, इसका मतलब है कि आपका ढेर बहुत भरा है। लेकिन इसका मतलब दो चीजों में से एक हो सकता है:

  • ढेर आपके आवेदन की आवश्यकताओं के लिए बहुत छोटा है।

  • आपके एप्लिकेशन में मेमोरी लीक है।

आप मान सकते हैं कि समस्या पूर्व है और केवल ढेर आकार में वृद्धि करें। लेकिन यदि वास्तविक समस्या उत्तरार्द्ध है, तो ढेर का आकार बढ़ाना सिर्फ अपरिहार्य है ... और सही करने के लिए और मेमोरी लीक को ठीक करें।


System.gc() पर कॉल न करें। यह मदद नहीं करेगा।

+0

मैं ढेर के उपयोग की निगरानी के लिए jvisualvm का उपयोग कर रहा हूं, अधिकतम आकार 1 जीबी है और उपयोग 200 एमबी से 600 एमबी के बीच भिन्न होता है, इसलिए यह सीमा से बहुत दूर है। – otonakav

+0

@otonakav - शायद आपके जीसी ट्यूनिंग पैरामीटर के साथ कुछ समस्या है। –

1

क्या आप एक ही कक्षा को कई बार लोड कर रहे हैं? क्योंकि आपको भारित वर्ग को कैश करना चाहिए।

यदि नहीं, तो आप कितनी कक्षाएं लोड कर रहे हैं? यदि वे बहुत हैं तो आपको लोड की गई कक्षाओं की सीमा को ठीक करना पड़ सकता है (यह संख्या या तो ढेर आकार या एक संख्या के आधार पर हो सकती है कि लोड किए गए वर्ग में कितनी मेमोरी होती है) और लोड होने पर कम से कम उपयोग को छोड़ दें अगला।

+0

संभवत: एक सीमा लोड करने के लिए एक सीमा होगी जो मैं कक्षा लोडर को संदर्भित करता हूं ताकि जीसी कई बार नहीं चल सके, लेकिन मुझे लगता है कि जीसी नहीं चलाएगा यदि बहुत सारे ढेर और पर्मगेन हैं क्योंकि मैं एक वर्ग लोडर का संदर्भ नहीं देता, विशेष रूप से यदि यह ओवरहेड सीमा पारित करने जा रहा है। – otonakav

+0

मैं यह इंगित करने की कोशिश कर रहा था कि यह समस्या वर्ग लोडर के उपयोग में हो सकती है न कि क्लास लोडर स्वयं। –

1

मेरे पास कक्षा अनलोडिंग के साथ कुछ समान स्थिति थी।

मैं जुनीट टेस्ट के अंदर कई जेवीएम अनुकरण करने के लिए कई क्लास लोडर का उपयोग कर रहा हूं (यह आमतौर पर ओरेकल कोहेरेंस क्लस्टर के साथ काम करने के लिए प्रयोग किया जाता है, लेकिन मुझे भी सफलतापूर्वक इस तकनीक का उपयोग JVM के अंदर बहु ​​नोड एचबीज़/हाडोप क्लस्टर शुरू करने के लिए किया गया था।)।

विभिन्न कारणों से परीक्षणों को ऐसे "वर्चुअल" जेवीएम को पुनरारंभ करने की आवश्यकता हो सकती है, जिसका अर्थ है पुराने क्लासलोडर को जब्त करना और नया बनाना।

कभी-कभी जेवीएम पूर्ण जीसी के लिए कक्षा अनलोडिंग ईवेंट में देरी करता है, जो बाद में विभिन्न समस्याओं का कारण बनता है।

एक तकनीक जिसे मैंने उपयोगी रूप से पर्मस्पेस एकत्र करने के लिए JVM को मजबूर करने के लिए पाया है, निम्नलिखित है।

public static void forcePermSpaceGC(double factor) { 
    if (PERM_SPACE_MBEAN == null) { 
     // probably not a HotSpot JVM 
     return; 
    } 
    else { 
     double f = ((double)getPermSpaceUsage())/getPermSpaceLimit(); 
     if (f > factor) { 

      List<String> bloat = new ArrayList<String>(); 
      int spree = 0; 
      int n = 0; 
      while(spree < 5) { 
       try { 
        byte[] b = new byte[1 << 20]; 
        Arrays.fill(b, (byte)('A' + ++n)); 
        bloat.add(new String(b).intern()); 
        spree = 0; 
       } 
       catch(OutOfMemoryError e) { 
        ++spree; 
        System.gc(); 
       } 
      } 
      return; 
     } 
    } 
} 

Full sourcecode

मैं JVM तक intern() का उपयोग कर उन्हें इकट्ठा होता स्ट्रिंग के साथ PermSpace भरने कर रहा हूँ।

लेकिन

  • मैं
  • हार्डवेयर/JVM संस्करण के विभिन्न संयोजन के परीक्षण के विभिन्न सीमा की आवश्यकता हो सकती है कि तकनीक का उपयोग कर रहा हूँ, तो यह अक्सर जल्दी बजाय मजबूर ठीक से इकट्ठा करने के लिए की पूरी JVM को पुनः आरंभ करने के लिए है सभी कचरा
संबंधित मुद्दे