"Java.lang.OutOfMemoryError: PermGen space" त्रुटि से निपटना


1222

हाल ही में मैं अपने वेब एप्लिकेशन में इस त्रुटि में भाग गया:

java.lang.OutOfMemoryError: PermGen space

यह एक विशिष्ट हाइबरनेट / जेपीए + आइसफेस / जेएसएफ एप्लीकेशन है जो टॉमकैट 6 और जेडीके 1.6 पर चल रहा है। जाहिरा तौर पर यह एक आवेदन को कुछ बार फिर से तैयार करने के बाद हो सकता है।

इसके कारण क्या हैं और इससे बचने के लिए क्या किया जा सकता है? मैं समस्या को कैसे ठीक करूं?


मैंने इसके लिए घंटों लड़ाई लड़ी है, लेकिन मेरे पास कोई अच्छी खबर नहीं है। मेरा संबंधित प्रश्न देखें: stackoverflow.com/questions/1996088/… आपके पास अभी भी एक मेमोरी लीक हो सकती है, जैसे कि कक्षाएं कचरा एकत्र नहीं की जाती हैं क्योंकि आपका WebAppClassLoader कचरा इकट्ठा नहीं होता है (इसका एक बाहरी संदर्भ है जिसे साफ़ नहीं किया गया है)। PermGen को बढ़ाने से केवल OutOfMemoryError में देरी होगी, और क्लास कचरा संग्रहण की अनुमति देना एक पूर्व शर्त है, लेकिन यदि क्लास लोडर के पास अभी भी इसके संदर्भ हैं, तो वे कक्षाएं एकत्र नहीं करेंगे।
एरन मेडन

मुझे यह त्रुटि प्रदर्शन टैगलिब जोड़ने में मिली । इसे हटाने से त्रुटि भी हल हो गई। ऐसा क्यों?
मस्त

और आप इसमें कैसे भागे?
थोरबजोरन रेव एंडरसन

13
JDK 1.8 का उपयोग करें: Ry MetaSpace में आपका स्वागत है
Rytek

यदि विंडोज का उपयोग कर रहे हैं, तो इन निर्देशों का पालन करने के बजाय मैन्युअल फ़ाइलों में झंडे सेट करने का प्रयास करें। यह ठीक से रनटाइम के दौरान टॉमकैट द्वारा कॉल की जाने वाली रजिस्ट्री में मान सेट करता है। stackoverflow.com/questions/21104340/…
MacGyver

जवाबों:


563

टॉमकैट शुरू होने पर जेवीएम कमांड लाइन में इन झंडे को जोड़ने का समाधान किया गया था:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

आप यह कर सकते हैं कि टॉमकैट सेवा को बंद करके, फिर टॉमकैट / बिन निर्देशिका में जाकर टॉमकैट 6w.exe चलाएं। "जावा" टैब के तहत, "जावा विकल्प" बॉक्स में तर्क जोड़ें। "ओके" पर क्लिक करें और फिर सेवा को पुनरारंभ करें।

यदि आपको कोई त्रुटि मिलती है तो निर्दिष्ट सेवा आपके द्वारा चलाए जाने वाले इंस्टॉल किए गए सेवा के रूप में मौजूद नहीं है :

tomcat6w //ES//servicename

जहाँ servicename सर्वर का नाम है जैसा कि services.msc में देखा गया है

स्रोत: पर orx की टिप्पणी एरिक के चंचल जवाब


39
नीचे दिए गए लेख से पता चलता है -XX: + UseConcMarkSweepGC और -XX: MaxPermSize = 128m साथ ही। my.opera.com/karmazilla/blog/2007/03/13/…
टेलर लेसे

30
-XX: + CMSPermGenSweepingEnabled यह विकल्प प्रदर्शन को कम करता है। यह प्रत्येक अनुरोध को हमारे सिस्टम पर सामान्य से तीन गुना अधिक समय लेता है। देखभाल के साथ उपयोग करें।
एल्डेलशेल

10
मेरे लिए काम किया - धन्यवाद - मैं टॉमबेट 6 के साथ उबंटू 10.10 पर यह कर रहा हूं - मैंने एक नई फ़ाइल बनाई: /usr/share/tomcat6/bin/setenv.sh और उसके बाद निम्न पंक्ति जोड़ी: JAVI_OPTS = "- Xms256m -Xmx512m - XX: + CMSClassUnloadingEnabled -XX: + CMSPermGenSweepingEnabled "- का उपयोग कर बिल्ला को पुनः आरंभ: sudo /etc/init.d/tomcat6 शुरू
सामी

24
Tomcat 6.0.29 स्टार्टअप पर, मेरे कैटालिना.आउट लॉगफाइल से: "कृपया CMSPassGnloadingEnabled की जगह CMSPermGenSweepingEnabled in future"
knul

222
सबसे पहले यह समझाना बहुत अच्छा होगा कि ये झंडे वास्तव में क्या करते हैं। बस कह रही है: "ऐसा करो और आनंद लो" पर्याप्त IMHO नहीं है।
निकम

251

आप -XX:MaxPermSize=128Mइसके बजाय बेहतर प्रयास करते हैं -XX:MaxPermGen=128M

मैं इस मेमोरी पूल के सटीक उपयोग के बारे में नहीं बता सकता, लेकिन इसका संबंध जेवीएम में भरी कक्षाओं की संख्या से है। (इस प्रकार टॉमकैट के लिए क्लास को लोड करने में सक्षम करने से समस्या का समाधान हो सकता है।) यदि आपके एप्लिकेशन रन बनाते हैं और रन पर कक्षाएं संकलित करते हैं, तो यह डिफ़ॉल्ट से बड़े मेमोरी पूल की आवश्यकता है।


9
वास्तव में, यह केवल OOMError को स्थगित करेगा। नीचे दिए गए जवाब को देखें, जो कि फ्रैंक के द्वारा शुरू किए गए हैं, जो कि फ्रैंककिविएट ब्लॉग के दो लिंक हैं।
राड_303

इन विकल्पों को यहाँ समझाया गया है: oracle.com/technetwork/java/javase/tech/…
amos

153

कई सर्वरों के बाद होने वाली ऐप सर्वर PermGen त्रुटियाँ आपके पुराने ऐप्स के क्लास लोडर में कंटेनर द्वारा रखे गए संदर्भों के कारण होती हैं। उदाहरण के लिए, एक कस्टम लॉग लेवल क्लास का उपयोग करने से ऐप सर्वर के क्लास लोडर द्वारा संदर्भ लिया जाएगा। आप इन इंटर-क्लास लोडर लीक का पता लगाकर आधुनिक (JDK6 +) JVM विश्लेषण टूल जैसे कि जम्प और jhat देख सकते हैं कि आपके ऐप में कौन सी कक्षाएं जारी हैं, और उनके उपयोग को फिर से डिज़ाइन या समाप्त कर रहा है। सामान्य संदिग्ध डेटाबेस, लॉगर और अन्य बेस-फ्रेमवर्क-स्तरीय लाइब्रेरी हैं।

देखें क्लास लोडर लीक: खूंखार "java.lang.OutOfMemoryError: PermGen space" अपवाद , और विशेष रूप से इसके अनुवर्ती पोस्ट


3
यह समस्या का केवल सही समाधान है, कुछ मामलों में सक्षम भी लागू करने के लिए बहुत मुश्किल है।
Rade_303

एक और बहुत अच्छा स्रोत People.apache.org/~markt/pretations/… ( टॉमकैट रिलीज़ मैनेजर से) है।)
गवेंको

22
जब भी यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, तो उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर होगा
जोआचिम सॉर

68

आम गलतियाँ लोग सोच रहे हैं कि हीप स्पेस और पर्मगेन स्पेस एक ही हैं, जो बिल्कुल भी सच नहीं है। आप ढेर में बहुत जगह बचा सकते हैं लेकिन फिर भी परमिटेन में मेमोरी से बाहर निकल सकते हैं।

PermGen में OutofMemory के सामान्य कारणों में ClassLoader है। जब भी क्लास को JVM में लोड किया जाता है, तो क्लास लोडर के साथ उसके सभी मेटा डेटा को PermGen एरिया पर रखा जाता है और जब क्लास लोडर ने उन्हें लोड किया तो वे कचरा एकत्र करने के लिए तैयार हो जाएंगे। केस क्लास लोडर में एक मेमोरी रिसाव होता है, जिसके द्वारा लोड की गई सभी कक्षाएं मेमोरी में बनी रहेंगी और एक बार फिर से इसे दोहराए जाने के बाद पर्मोफेमोरी का कारण बनेगी। शास्त्रीय उदाहरण Java.lang.OutOfMemoryError: Tomcat में PermGen Space है

अब इसे हल करने के दो तरीके हैं:
1. मेमोरी लीक का कारण खोजें या यदि कोई मेमोरी लीक है।
2. जेवीएम परम का उपयोग करके पर्मगेन स्पेस का आकार बढ़ाएं -XX:MaxPermSizeऔर -XX:PermSize

आप अधिक जानकारी के लिए जावा में 2 समाधान Java.lang.OutOfMemoryError भी देख सकते हैं ।


3
कैसे पास करें -XX:MaxPermSize and -XX:PermSize?? मैं नहीं मिल सकता है catalina.bat। मेरा टॉमकैट संस्करण है 5.5.26
डेकार्ड

क्लास लोडर की मेमोरी लीक कैसे पता करें? क्या आप कोई टूल सुझाते हैं?
अमित

@ उपकरण की सिफारिशों के लिए, इस प्रश्न पर सामुदायिक विकि उत्तर देखें।
बरेठ

@ डॉकर्ड टॉमकैट / बिन डायरेक्टरी में जा रहा है और tomcat6w.exe चला रहा है। "जावा" टैब के तहत, "जावा विकल्प" बॉक्स में तर्क जोड़ें। "ओके" पर क्लिक करें
ज़ेब

43

-XX:MaxPermSize=128mसूर्य JVM के लिए कमांड लाइन पैरामीटर का उपयोग करें (जाहिर है कि आपको जो भी आकार की आवश्यकता है, उसके लिए 128 प्रतिस्थापन)।


9
एकमात्र मुद्दा यह है कि आप अपरिहार्य रूप से देरी कर रहे हैं- किसी समय आप हेडरूम से बाहर भी दौड़ेंगे। यह एक शानदार व्यावहारिक समाधान है, लेकिन यह इसे स्थायी रूप से हल नहीं करता है।
टिम होलैंड

एक ही बात ग्रहण में होती है और किसी भी समय आपके पास बहुत सारे गतिशील वर्ग लोड होते हैं। सहपाठियों का निपटान नहीं किया जाता है और सभी अनंत काल के लिए स्थायी पीढ़ी में रहते हैं
मैट

1
मैं एक विशेष रूप से बड़े हडसन की नौकरी को अंजाम देते समय पर्मगेन से बाहर चल रहा था ... यह मेरे लिए तय किया।
एचडीवी

10
@ टिमहॉलैंड, यह एक स्थाई फिक्स हो सकता है यदि मूल कारण क्लास लोडर रिसाव नहीं है, तो बस आपके वेब ऐप में कई कक्षाएं / स्थिर डेटा।
पेटर टॉर्क

स्रोत से जेनकींस / हडसन का निर्माण करते समय एचडीवे के समान मुद्दा मिला।
लूसीगैब

38

कोशिश करो -XX:MaxPermSize=256mऔर अगर यह बनी रहती है, कोशिश करो-XX:MaxPermSize=512m


56
और अगर यह अभी भी जारी रहता है XX:MaxPermSize=1024m:)
igo

38
और अगर यह अभी भी जारी रहता है तो XX की कोशिश करें: MaxPermSize = 2048m :)
थॉमस

16
और अगर यह जारी रहता है, तो अपने आवेदन पर पुनर्विचार करें !! या XX की कोशिश करें: MaxPermSize = 4096m :)
जोनाथन ऐरे

17
तुम भी 8192 मीटर की कोशिश कर सकते हैं, लेकिन कुछ हद तक ओवरलेस है
Jacek Pietal

12
ओवरकिल वास्तव में - 640KB किसी के लिए पर्याप्त होना चाहिए!
जोएल पुर्रा

28

मैंने जोड़ा -XX: MaxPermSize = 128m (आप प्रयोग कर सकते हैं जो वीएम तर्क के लिए सबसे अच्छा काम करता है) जैसा कि मैं ग्रहण विचार का उपयोग कर रहा हूं। JVM के अधिकांश में, डिफ़ॉल्ट PermSize 64MB के आसपास है , जो कि कई वर्गों या परियोजना में बड़ी संख्या में स्ट्रिंग्स होने पर मेमोरी से बाहर निकलता है।

ग्रहण के लिए, यह भी उत्तर में वर्णित है ।

चरण 1 : सर्वर टैब पर टॉमकैट सर्वर पर डबल क्लिक करें

यहां छवि विवरण दर्ज करें

चरण 2 : ओपन लॉन्च कॉन्फिडेंस और -XX: MaxPermSize = 128mमौजूदा वीएम बहस के अंत में जोड़ें ।

यहां छवि विवरण दर्ज करें


1
आपके सर्वोत्तम विस्तृत उत्तर के लिए धन्यवाद (नोट: "कॉन्फ़िगरेशन लॉन्च करें" विंडो खोलने के लिए "ओपन लॉन्च कॉन्फ़िगरेशन" पर क्लिक करें ... लेकिन मैंने निम्नलिखित मापदंडों का उपयोग किया: "-XX: + CMSClassUnloadingEnabled -XX: + CMSPermGnSweepingEnabled"
क्रिस सिम

23

मैं एक जटिल वेब एप्लिकेशन को भी तैनात और तैयार नहीं करते हुए इस समस्या के खिलाफ अपना सिर झुका रहा हूं, और मैंने सोचा कि मैं एक स्पष्टीकरण और मेरा समाधान जोड़ूंगा।

जब मैं Apache Tomcat पर एक एप्लिकेशन को तैनात करता हूं, तो उस ऐप के लिए एक नया ClassLoader बनाया जाता है। तब ClassLoader का उपयोग सभी एप्लिकेशन की कक्षाओं को लोड करने के लिए किया जाता है, और undeploy पर, सब कुछ अच्छी तरह से दूर जाना है। हालांकि, वास्तव में यह उतना सरल नहीं है।

वेब एप्लिकेशन के जीवन के दौरान बनाई गई एक या अधिक कक्षाएं एक स्थिर संदर्भ रखती हैं, जो कहीं-कहीं लाइन के साथ, क्लासऑलाडर का संदर्भ देती है। जैसा कि संदर्भ मूल रूप से स्थिर है, कचरा संग्रह की कोई भी राशि इस संदर्भ को साफ नहीं करेगी - क्लासॉलाडर, और सभी वर्ग जो इसे लोड किए गए हैं, यहां रहने के लिए हैं।

और redeploys के एक जोड़े के बाद, हम OutOfMemoryError से मुठभेड़ करते हैं।

अब यह काफी गंभीर समस्या बन गई है। मैं यह सुनिश्चित कर सकता था कि प्रत्येक redeploy के बाद Tomcat को फिर से शुरू किया जाए, लेकिन यह पूरे सर्वर को नीचे ले जाता है, बजाय इसके कि केवल एप्लिकेशन को redeployed किया जाए, जो अक्सर संभव नहीं होता है।

इसलिए इसके बजाय मैंने कोड में एक समाधान डाला है, जो Apache Tomcat 6.0 पर काम करता है। मैंने किसी अन्य एप्लिकेशन सर्वर पर परीक्षण नहीं किया है, और इस बात पर जोर देना चाहिए कि यह बहुत संभव है कि किसी अन्य एप्लिकेशन सर्वर पर संशोधन के बिना काम न करे

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

वैसे भी, कोड के साथ। इसे उस बिंदु पर बुलाया जाना चाहिए, जहां एप्लिकेशन undeploying है - जैसे कि सर्वलेट की विध्वंस विधि या (बेहतर दृष्टिकोण) एक सर्वलेटकोटेक्स्टलेनर के संदर्भडिस्ट्रोइड विधि।

//Get a list of all classes loaded by the current webapp classloader
WebappClassLoader classLoader = (WebappClassLoader) getClass().getClassLoader();
Field classLoaderClassesField = null;
Class clazz = WebappClassLoader.class;
while (classLoaderClassesField == null && clazz != null) {
    try {
        classLoaderClassesField = clazz.getDeclaredField("classes");
    } catch (Exception exception) {
        //do nothing
    }
    clazz = clazz.getSuperclass();
}
classLoaderClassesField.setAccessible(true);

List classes = new ArrayList((Vector)classLoaderClassesField.get(classLoader));

for (Object o : classes) {
    Class c = (Class)o;
    //Make sure you identify only the packages that are holding references to the classloader.
    //Allowing this code to clear all static references will result in all sorts
    //of horrible things (like java segfaulting).
    if (c.getName().startsWith("com.whatever")) {
        //Kill any static references within all these classes.
        for (Field f : c.getDeclaredFields()) {
            if (Modifier.isStatic(f.getModifiers())
                    && !Modifier.isFinal(f.getModifiers())
                    && !f.getType().isPrimitive()) {
                try {
                    f.setAccessible(true);
                    f.set(null, null);
                } catch (Exception exception) {
                    //Log the exception
                }
            }
        }
    }
}

classes.clear();

मुझे पता है कि मुझे यह लिखते हुए 8 साल से अधिक हो गए हैं, लेकिन कहीं न कहीं तब और अब के बीच में मुझे एक गहरा मूल कारण और समाधान मिला। यह था कि जबकि वेबएप के सभी वर्ग संदर्भ क्लास लोडर के स्वामित्व में हैं, स्टार्टअप और शटडाउन कॉलबैक को लागू करने वाले धागे का स्वामित्व अभिभावक क्लास लोडर के पास है। इसका मतलब यह है कि यदि शटडाउन कोड एक थ्रेड-लोकल वैरिएबल को इनिशियलाइज़ करता है, तो यह पेरेंट क्लास लोडर को क्लीयरेंस को अच्छी तरह से रोकते हुए, रेफरेंस क्लास लोडर के लिए एक रेफ़रेंस को समाप्त कर देगा।
एडवर्ड टॉर्बेट

सौभाग्य से, एक बहुत ही सरल सुधार है - सभी कोड को वर्तमान में शटडाउन विधि में एक नई थ्रेड ऑब्जेक्ट की रन विधि में स्थानांतरित करें। फिर शटडाउन विधि में, इस धागे को शुरू करें और इसके पूरा होने की प्रतीक्षा करें। सफाई कोड को निष्पादित रूप से निष्पादित किया जाएगा, लेकिन कोई भी थ्रेड-स्थानीय चर लीक होने के बजाय संदर्भ क्लास लोडर के लिए बाध्य रहेगा।
एडवर्ड टॉर्बेट

20

java.lang.OutOfMemoryError: PermGenअंतरिक्ष संदेश बताता है कि स्मृति में स्थायी पीढ़ी के क्षेत्र समाप्त हो रहा है।

किसी भी जावा एप्लिकेशन को सीमित मात्रा में मेमोरी का उपयोग करने की अनुमति है। आपके विशिष्ट एप्लिकेशन द्वारा उपयोग की जाने वाली मेमोरी की सटीक मात्रा एप्लिकेशन स्टार्टअप के दौरान निर्दिष्ट की जाती है।

जावा मेमोरी को अलग-अलग क्षेत्रों में अलग किया जाता है जिसे निम्नलिखित छवि में देखा जा सकता है:

यहां छवि विवरण दर्ज करें

मेटास्पेस: एक नई मेमोरी स्पेस का जन्म हुआ है

JDK 8 हॉटस्पॉट JVM अब क्लास मेटाडेटा के प्रतिनिधित्व के लिए देशी मेमोरी का उपयोग कर रहा है और इसे मेटास्पेस कहा जाता है; Oracle JRockit और IBM JVM के समान है।

अच्छी खबर यह है कि इसका मतलब यह नहीं है कि java.lang.OutOfMemoryError: PermGenआपको और अधिक स्पेस की समस्या है और आपको इस मेमोरी स्पेस को Java_8_Download या उच्चतर का उपयोग करके ट्यून करने और मॉनिटर करने की कोई आवश्यकता नहीं है ।


17

1) पर्मेन मेमोरी का आकार बढ़ाना

पहली बात यह है कि स्थायी पीढ़ी के ढेर के आकार को बड़ा करना है। यह सामान्य -Xms (आरंभिक हीप आकार सेट) और –Xmx (अधिकतम हीप आकार सेट) JVM तर्कों के साथ नहीं किया जा सकता है, जैसा कि उल्लेख किया गया है, स्थायी पीढ़ी हीप स्थान पूरी तरह से नियमित जावा हीप स्थान से अलग है, और ये तर्क सेट हैं इस नियमित जावा हीप स्थान के लिए स्थान। हालांकि, समान तर्क हैं जिनका उपयोग किया जा सकता है (कम से कम सूर्य / OpenJDK jvms के साथ) स्थायी पीढ़ी के आकार को बड़ा बनाने के लिए:

 -XX:MaxPermSize=128m

डिफ़ॉल्ट 64 मी है।

2) स्वीपिंग सक्षम करें

एक और तरीका है कि अच्छे के लिए देखभाल करने के लिए कक्षाओं को उतारने की अनुमति है ताकि आपका पर्मगेन कभी बाहर न निकले:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

उस तरह की सामग्री ने मेरे लिए अतीत में जादू का काम किया। एक बात हालांकि, उन का उपयोग करने में एक महत्वपूर्ण प्रदर्शन व्यापार है, क्योंकि परमिटेन स्वीप्स आपके द्वारा किए गए प्रत्येक अनुरोध के लिए अतिरिक्त 2 अनुरोधों या उन लाइनों के साथ कुछ और करेंगे। आपको ट्रेडऑफ़ के साथ अपने उपयोग को संतुलित करना होगा।

आप इस त्रुटि का विवरण पा सकते हैं।

http://faisalbhagat.blogspot.com/2014/09/java-outofmemoryerror-permgen.html



विकल्प 2 महान है, लेकिन बस चेतावनी दी जाती है कि इसका उपयोग उत्पादन वातावरण में नहीं किया जाना चाहिए। आमतौर पर इसे केवल विकास के वातावरण में रखने के लिए सबसे अच्छा है। हालाँकि, PermGen को Java 8 के रूप में हटा दिया गया है। Openjdk.java.net/jeps/122
HDost

16

वैकल्पिक रूप से, आप JRockit पर स्विच कर सकते हैं जो permgen को अलग तरह से संभालता है फिर सूरज की jvm। आमतौर पर इसका प्रदर्शन बेहतर होता है।

http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html


4
जबकि JRockit के पास वास्तव में कोई PermGen नहीं है, लेकिन यह लंबे समय में मदद नहीं करेगा। आपको java.lang.OutOfMemoryError: There is insufficient native memoryइसके बदले मिलेगा ।
स्ट्राक्ट्रेसर

14

हमारे पास यहां जिस समस्या के बारे में हम बात कर रहे हैं, वह मेरा परिदृश्य ग्रहण-हेलियोस + टॉमकैट + जेएसएफ है और आप जो कर रहे थे, वह एक सरल अनुप्रयोग को टॉमकैट के लिए तैनात कर रहा है। मैं यहाँ एक ही समस्या दिखा रहा था, इसे इस प्रकार हल किया।

ग्रहण में, सर्वर टैब पर जाएं मेरे मामले में पंजीकृत सर्वर पर 7.0 डबल क्लिक करें, यह मेरे फाइल सर्वर को सामान्य पंजीकरण जानकारी खोलता है। "सामान्य सूचना" अनुभाग पर "ओपन लॉन्च कॉन्फ़िगरेशन" लिंक पर क्लिक करें , यह वीएम तर्कों में तर्क टैब में सर्वर विकल्पों के निष्पादन को खोलता है, जो इन दो प्रविष्टियों के अंत में जोड़े गए हैं

-XX: MaxPermSize = 512m
-XX: PermSize = 512m

और त्यार।


14

इन दिनों सबसे सरल उत्तर जावा 8 का उपयोग करना है।

यह अब पर्मेन स्पेस के लिए विशेष रूप से मेमोरी को सुरक्षित रखता है, जिससे पर्मगेन मेमोरी को नियमित मेमोरी पूल के साथ सह-मिलिंग करने की अनुमति मिलती है।

ध्यान रखें कि -XXPermGen...=...यदि आप जावा 8 नहीं चाहते हैं कि वे कुछ भी न करें, तो आपको सभी गैर-मानक जेवीएम स्टार्टअप मापदंडों को हटाना होगा ।


नमस्कार, यह उत्तर पहले ही दिया जा चुका है: stackoverflow.com/a/22897121/505893 । कृपया अपना उत्तर हटाएं, स्पष्टता के लिए। जरूरत पड़ने पर आप मेरे द्वारा बताए गए उत्तर को सुधार सकते हैं। धन्यवाद;)
नीले

6
@ बब्लूश आपको उस ओर इशारा करने के लिए धन्यवाद; हालाँकि, यह उत्तर आउटऑफमेमोरी एक्सेप्शन और मेटाडेटा को लीक करने के बारे में बात करने में सभी बग़ल में है। यह PermGen विकल्प को हटाने के बहुत महत्वपूर्ण बिंदुओं का उल्लेख करने में भी विफल रहता है। संक्षेप में, मुझे यकीन नहीं है कि मैं उत्तर में सुधार करूंगा, बल्कि इसे फिर से लिखूंगा। यदि यह सिर्फ एक त्वरित टच-अप था, तो मुझे कम हिचकिचाहट महसूस होगी, लेकिन ऐसा लगता है कि यह एक त्वरित टच-अप की तुलना में बहुत अधिक होगा, और मुझे मूल लेखक से घृणा होगी। फिर भी, यह उत्तर सूची एक गड़बड़ कुत्ते का खाना है, और शायद मेरी पोस्ट को मारना वैसे भी सबसे अच्छा होगा।
एडविन बक

8
  1. टॉमकैट की बिन डायरेक्टरी से टोमकैट 7w खोलें या स्टार्ट मेन्यू में मॉनिटर टॉम्कट टाइप करें (विभिन्न सेवाओं के साथ एक टैब्ड विंडो खुलती है)।
  2. जावा विकल्प टेक्स्ट क्षेत्र में इस लाइन को जोड़ें:

    -XX:MaxPermSize=128m
  3. आरंभिक मेमोरी पूल को 1024 (वैकल्पिक) पर सेट करें।
  4. अधिकतम मेमोरी पूल को 1024 (वैकल्पिक) पर सेट करें।
  5. ओके पर क्लिक करें।
  6. Tomcat सेवा को पुनरारंभ करें।

6

पर्म जीन स्पेस त्रुटि बड़ी जगह के उपयोग के कारण होती है, बल्कि jvm ने कोड निष्पादित करने के लिए स्थान प्रदान किया।

UNIX ऑपरेटिंग सिस्टम में इस समस्या का सबसे अच्छा समाधान है bash फ़ाइल पर कुछ कॉन्फ़िगरेशन बदलना। निम्न चरण समस्या को हल करते हैं।

gedit .bashrcटर्मिनल पर कमांड चलाएं ।

JAVA_OTPSनिम्नलिखित मान के साथ चर बनाएं :

export JAVA_OPTS="-XX:PermSize=256m -XX:MaxPermSize=512m"

बैश फ़ाइल सहेजें। टर्मिनल पर रन कमांड का बैश। सर्वर को पुनरारंभ करें।

मुझे उम्मीद है कि यह दृष्टिकोण आपकी समस्या पर काम करेगा। यदि आप 8 से कम जावा संस्करण का उपयोग करते हैं तो यह समस्या कभी-कभी होती है। लेकिन अगर आप Java 8 का उपयोग करते हैं तो समस्या कभी नहीं होगी।


5

यदि आपके पास वास्तविक मेमोरी लीक है तो स्थायी जनरेशन साइज बढ़ाने या जीसी मापदंडों को बढ़ाने में मदद नहीं मिलेगी। यदि आपका एप्लिकेशन या उसका उपयोग करने वाला कोई थर्ड पार्टी लाइब्रेरी है, तो क्लास लोडर को केवल वास्तविक और स्थायी समाधान लीक करता है, इस लीक को खोजने और उसे ठीक करने के लिए। ऐसे कई उपकरण हैं जो आपकी मदद कर सकते हैं, हाल ही में एक प्लमब्र है , जिसने आवश्यक क्षमताओं के साथ एक नया संस्करण जारी किया है।


5

यदि आप अपने वेबऐप में log4j का उपयोग कर रहे हैं, तो भी log4j प्रलेखन में इस पैराग्राफ की जांच करें ।

ऐसा लगता है कि यदि आप उपयोग कर रहे हैं PropertyConfigurator.configureAndWatch("log4j.properties"), तो आप स्मृति रिसाव का कारण बनते हैं जब आप अपने वेबप को अनप्लॉय करते हैं।


4

मैं हाइबरनेट + ग्रहण आरसीपी का एक संयोजन, उपयोग करने की कोशिश की है -XX:MaxPermSize=512mऔर -XX:PermSize=512mऔर यह मेरे लिए काम कर रहा है।


4

सेट करें -XX:PermSize=64m -XX:MaxPermSize=128m। बाद में आप भी बढ़ने की कोशिश कर सकते हैं MaxPermSize। आशा है कि यह काम करेगा। मेरे लिए वही काम करता है। केवल सेट करना MaxPermSizeमेरे लिए काम नहीं किया।


4

मैंने कई जवाबों की कोशिश की और केवल एक चीज जो अंत में काम की थी वह थी पोम में संकलक प्लगइन के लिए कॉन्फ़िगरेशन:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <fork>true</fork>
        <meminitial>128m</meminitial>
        <maxmem>512m</maxmem>
        <source>1.6</source>
        <target>1.6</target>
        <!-- prevent PermGen space out of memory exception -->
        <!-- <argLine>-Xmx512m -XX:MaxPermSize=512m</argLine> -->
    </configuration>
</plugin>

आशा है कि यह मदद करता है।


"argLine" मावेन-कंपाइलर-प्लगइन 2.4 द्वारा मान्यता प्राप्त नहीं है। यह केवल "कंपाइलर एर्ग्यूमेंट" का समर्थन करता है, जो त्रुटि देता है: <compilerArgument> -XX: MaxPermSize = 256m </ compilerArgument> [ERROR] जेवैक को अंजाम देने में असफलता, लेकिन त्रुटि को पार्स नहीं कर सका: javac: अमान्य ध्वज: -xP MaxSize = 256 : javac <Options> <source files>
Alex

यदि आपका संकलन चरण permgen से बाहर चल रहा है, तो maven-compiler-plugin पर <compilerArgument> सेट करें। यदि यूनिट परीक्षण मावेन-अचूक-प्लगइन में पर्मगेन सेट <argLine> से बाहर चल रहे हैं
qwerty

4

यह मेरे लिए भी हल; हालाँकि, मैंने देखा कि सर्वलेट पुनः आरंभ करने का समय बहुत बुरा था, इसलिए जब यह उत्पादन में बेहतर था, तो यह विकास में एक तरह का खिंचाव था।


3

मेमोरी का कॉन्फ़िगरेशन आपके ऐप की प्रकृति पर निर्भर करता है।

तुम क्या कर रहे हो?

लेन-देन की राशि पहले से क्या है?

आप कितना डेटा लोड कर रहे हैं?

आदि।

आदि।

आदि

संभवतः आप अपने ऐप को प्रोफाइल कर सकते हैं और अपने ऐप से कुछ मॉड्यूल को साफ करना शुरू कर सकते हैं।

जाहिरा तौर पर यह एक आवेदन को कुछ बार फिर से तैयार करने के बाद हो सकता है

टॉम्कट में गर्म तैनाती होती है लेकिन यह स्मृति को खा जाती है। एक बार में अपने कंटेनर को पुनः आरंभ करने का प्रयास करें। साथ ही आपको उत्पादन मोड में चलाने के लिए आवश्यक मेमोरी की मात्रा जानना होगा, यह उस शोध के लिए अच्छा समय है।


3

वे कहते हैं कि बिलाव (6.0.28 या 6.0.29) के नवीनतम राजस्व सर्वलेट्स redeploying का काम करने में ज्यादा बेहतर है।


3

मैं वास्तव में एक ही समस्या में भागता हूं, लेकिन दुर्भाग्य से सुझाए गए समाधानों में से कोई भी वास्तव में मेरे लिए काम नहीं करता है। समस्या तैनाती के दौरान नहीं हुई थी, और मैं न तो कोई गर्म तैनाती कर रहा था।

मेरे मामले में समस्या मेरे वेब-एप्लिकेशन के निष्पादन के दौरान एक ही बिंदु पर हर बार हुई, डेटाबेस से कनेक्ट करते समय (हाइबरनेट के माध्यम से)।

इस लिंक (पहले भी उल्लिखित) ने समस्या को हल करने के लिए पर्याप्त जानकारी प्रदान की। WEB-INF से बाहर jdbc- (mysql) -driver को स्थानांतरित करने और jre / lib / ext / फ़ोल्डर में समस्या हल हो गई है। यह आदर्श समाधान नहीं है, क्योंकि एक नए JRE में अपग्रेड करने के लिए आपको ड्राइवर को फिर से स्थापित करना होगा। एक अन्य उम्मीदवार जो समान समस्याएं पैदा कर सकता है, वह लॉग 4 जे है, इसलिए आप उस एक को भी स्थानांतरित करना चाहते हैं


यदि आप ड्राइवर को jre / lib / ext में शामिल नहीं करना चाहते हैं, तो आप संभवतः अपने कंटेनर स्टार्टअप क्लासपाथ में ड्राइवर को शामिल करके समान परिणाम प्राप्त कर सकते हैं। java -cp /path/to/jdbc-mysql-driver.jar:/path/to/container/bootstrap.jar container.Start
Scott

3

इस तरह के मामले में पहला कदम यह जांचना है कि जीसी को परमिटेन से कक्षाएं अनलोड करने की अनुमति है या नहीं। मानक JVM इस संबंध में रूढ़िवादी है - कक्षाएं हमेशा के लिए जीने के लिए पैदा होती हैं। एक बार लोड होने के बाद, कक्षाएं स्मृति में रहती हैं, भले ही कोई कोड अब उनका उपयोग न कर रहा हो। यह तब समस्या बन सकता है जब एप्लिकेशन बहुत सारी कक्षाएं गतिशील रूप से बनाता है और उत्पन्न वर्गों को अधिक समय तक आवश्यकता नहीं होती है। ऐसे में जेवीएम को वर्ग परिभाषाओं को उतारने की अनुमति देना मददगार हो सकता है। यह आपके स्टार्टअप स्क्रिप्ट में सिर्फ एक कॉन्फ़िगरेशन पैरामीटर जोड़कर प्राप्त किया जा सकता है:

-XX:+CMSClassUnloadingEnabled

डिफ़ॉल्ट रूप से यह गलत पर सेट होता है और इसलिए इसे सक्षम करने के लिए आपको जावा विकल्प में निम्नलिखित विकल्प को स्पष्ट रूप से सेट करना होगा। यदि आप CMSClassUnloadingEnabled को सक्षम करते हैं, तो GC PermGen को भी स्वीप कर देगा और उन कक्षाओं को हटा देगा जिनका अब उपयोग नहीं किया जाता है। ध्यान रखें कि यह विकल्प तभी काम करेगा जब UseConcMarkSweepGC नीचे दिए गए विकल्प का उपयोग करने में भी सक्षम हो। इसलिए जब ParallelGC या, God मना करते हैं, तो सीरियल GC, सुनिश्चित करें कि आपने अपनी GC को CMS में निर्दिष्ट करके निर्धारित किया है:

-XX:+UseConcMarkSweepGC

3

टॉम्कट को अधिक मेमोरी असाइन करना उचित समाधान नहीं है।

सही समाधान संदर्भ नष्ट होने और पुनःप्राप्त (गर्म तैनाती) के बाद सफाई करना है। इसका उपाय मेमोरी लीक्स को रोकना है।

यदि आपका Tomcat / Webapp सर्वर आपको बता रहा है कि ड्राइवरों (JDBC) को अपंजीकृत करने में विफल रहा है, तो उन्हें अपंजीकृत करें। यह मेमोरी लीक को रोक देगा।

आप एक ServletContextListener बना सकते हैं और इसे अपने web.xml में कॉन्फ़िगर कर सकते हैं। यहाँ एक नमूना है ServletContextListener:

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

import com.mysql.jdbc.AbandonedConnectionCleanupThread;

/**
 * 
 * @author alejandro.tkachuk / calculistik.com
 *
 */
public class AppContextListener implements ServletContextListener {

    private static final Logger logger = Logger.getLogger(AppContextListener.class);

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        logger.info("AppContextListener started");
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        logger.info("AppContextListener destroyed");

        // manually unregister the JDBC drivers
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                logger.info(String.format("Unregistering jdbc driver: %s", driver));
            } catch (SQLException e) {
                logger.info(String.format("Error unregistering driver %s", driver), e);
            }

        }

        // manually shutdown clean up threads
        try {
            AbandonedConnectionCleanupThread.shutdown();
            logger.info("Shutting down AbandonedConnectionCleanupThread");
        } catch (InterruptedException e) {
            logger.warn("SEVERE problem shutting down AbandonedConnectionCleanupThread: ", e);
            e.printStackTrace();
        }        
    }
}

और यहाँ आप इसे अपने web.xml में कॉन्फ़िगर करते हैं:

<listener>
    <listener-class>
        com.calculistik.mediweb.context.AppContextListener 
    </listener-class>
</listener>  

2

"वे" गलत हैं क्योंकि मैं 6.0.29 चला रहा हूं और सभी विकल्पों को सेट करने के बाद भी यही समस्या है। जैसा कि टिम हावलैंड ने ऊपर कहा, ये विकल्प केवल अपरिहार्य हैं। वे मुझे हर बार रिडाइप करने के बजाय त्रुटि को रोकने से पहले 3 बार रिडिप्‍लाय करने की अनुमति देते हैं।


2

मामले में आप ग्रहण आईडीई में यह हो रही है, मानकों की स्थापना के बाद भी --launcher.XXMaxPermSize, -XX:MaxPermSize, आदि, अभी भी अगर आप एक ही त्रुटि हो रही है, यह सबसे अधिक संभावना है कि ग्रहण जो कुछ लोगों द्वारा स्थापित किया गया है | JRE की एक गाड़ी संस्करण का उपयोग कर रहा है तृतीय पक्ष एप्लिकेशन और डिफ़ॉल्ट पर सेट है। ये छोटी गाड़ी संस्करण PermSize पैरामीटर नहीं उठाते हैं और इसलिए जो भी आप सेट करते हैं, आप अभी भी इन मेमोरी त्रुटियों को प्राप्त कर रहे हैं। तो, अपने eclipse.ini में निम्नलिखित पैरामीटर जोड़ें:

-vm <path to the right JRE directory>/<name of javaw executable>

यह भी सुनिश्चित करें कि आपने ग्रहण के प्राथमिकताओं में डिफ़ॉल्ट JRE को जावा के सही संस्करण में सेट किया है।


2

मेरे लिए काम करने का एकमात्र तरीका JRockit JVM था। मेरे पास MyEclipse 8.6 है।

JVM का ढेर रनिंग जावा प्रोग्राम द्वारा उत्पन्न सभी ऑब्जेक्ट्स को संग्रहीत करता है। जावा newऑब्जेक्ट बनाने के लिए ऑपरेटर का उपयोग करता है , और नई वस्तुओं के लिए मेमोरी रन टाइम पर हीप पर आवंटित की जाती है। कचरा संग्रह उन वस्तुओं द्वारा निहित मेमोरी को स्वचालित रूप से मुक्त करने का तंत्र है जो अब प्रोग्राम द्वारा संदर्भित नहीं हैं।


2

मैं इसी तरह के मुद्दे पर चल रहा था। मेरा है JDK 7 + मावेन 3.0.2 + स्ट्रट्स 2.0 + Google GUICE निर्भरता इंजेक्शन आधारित परियोजना।

जब भी मैंने mvn clean packageकमांड चलाने की कोशिश की , यह निम्नलिखित त्रुटि दिखा रहा था और "बिल्ड फेल्योर" हुआ

org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; नेस्टेड अपवाद java.lang.reflect.InvocationTargetException: null java.lang.reflect.InvocationTargetException इसके कारण हैं: java.lang.OutOfMororyError: PermGen space

मैंने उपरोक्त सभी उपयोगी टिप्स और ट्रिक्स आजमाए लेकिन दुर्भाग्य से मेरे लिए कोई काम नहीं किया। मेरे लिए क्या काम किया गया है नीचे चरण दर चरण वर्णित है: =>

  1. अपने pom.xml पर जाएं
  2. निम्न को खोजें <artifactId>maven-surefire-plugin</artifactId>
  3. एक नया <configuration>तत्व जोड़ें और फिर <argLine>उप तत्व जिसमें -Xmx512m -XX:MaxPermSize=256mनीचे दिखाया गया है =>

<configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration>

आशा है कि यह मदद करता है, खुश प्रोग्रामिंग :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.