2014-06-11 3 views
9

कल मैंने अपने पहले Grails (2.3.6) ऐप को एक dev सर्वर पर तैनात किया और इसकी निगरानी करना शुरू कर दिया। मुझे बस एक स्वचालित मॉनीटर मिला है जिसमें कहा गया है कि सीपीयू को इस मशीन पर पिन किया गया था, और इसलिए मैंने इसमें एसएसएचड किया। मैं top चला गया और पाया कि यह मेरा जावा ऐप का पीआईडी ​​था जो सर्वर को पिन कर रहा था। मैंने यह भी देखा कि स्मृति 40% थी। कुछ सेकंड के बाद, सीपीयू पिनिंग बंद कर दिया, एक सामान्य स्तर पर चला गया, और स्मृति ~ 20% रेंज में वापस चला गया। क्लासिक प्रमुख जीसी।ग्रोवी/ग्रेल्स क्लासलोडर रिसाव को समझना

जब यह एकत्र हो रहा था, मैंने एक ढेर डंप किया था। जीसी के बाद, मैंने JVisualVM में डंप खोला और देखा कि अधिकांश मेमोरी org.codehaus.groovy.runtime.metaclass.MetaMethodIndex.Entry कक्षा के लिए आवंटित की जा रही थी। कुल मिलाकर लगभग 250,000 उदाहरण थे, लगभग 25 एमबी मेमोरी खा रहे थे।

मैंने इस कक्षा को गुगल किया और ultra helpful Javadocs पर एक नज़र डाली। तो मुझे अभी भी पता नहीं है कि यह वर्ग क्या करता है।

लेकिन गुगलिंग ने इस वर्ग से जुड़े एक दर्जन या उससे संबंधित लेख (उनमें से कुछ SO प्रश्न) और Grails/Groovy ऐप्स के साथ एक पर्मजेन/क्लासलोडर रिसाव भी लाया। और ऐसा लगता है कि मेरे ऐप ने वास्तव में जीसी के साथ इन 250 के उदाहरण को साफ कर लिया है, फिर भी यह परेशान है कि इसके कई उदाहरण थे, और जीसी ने सीपीयू को 5 मिनट से अधिक समय तक पिन किया।

मेरे सवालों का:

  • इस वर्ग क्या है और क्या ग्रूवी इसके साथ क्या कर रही है?
  • क्या कोई मुझे this answer समझा सकता है? -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled इस विशेष समस्या का उपयोग क्यों करेगा?
  • यह कक्षा विशेष रूप से PermGen के लिए परेशानी क्यों है?

उत्तर

12

ग्रोवी गतिशील भाषा है, प्रत्येक विधि कॉल गतिशील रूप से प्रेषित किया जाता है। ऑप्टिमाइज़ करने के लिए कि MetaClassRegistry में प्रत्येक java.lang.Class के लिए ग्रोवी MetaClass बनाता है। ये MetaClass उदाहरण कमजोर बनाते हैं और कमजोर संदर्भों का उपयोग करके संग्रहीत किए जाते हैं।

कारण आपको org.codehaus.groovy.runtime.metaclass.MetaMethodIndex.Entry का बहुत कुछ कारण है क्योंकि ग्रोवी कक्षाओं और विधियों में विधियों का नक्शा संग्रहीत कर रहा है ताकि उन्हें रनटाइम द्वारा तुरंत प्रेषित किया जा सके। आवेदन के आकार के आधार पर यह हो सकता है कि आपने हजारों वर्गों की खोज की है क्योंकि प्रत्येक वर्ग में कई बार सैकड़ों विधियां हो सकती हैं।

हालांकि, ग्रोवी और ग्रेल्स में कोई "स्मृति रिसाव" नहीं है, जो आप देख रहे हैं वह सामान्य व्यवहार है। आपका एप्लिकेशन मेमोरी पर कम चल रहा है, शायद इसलिए कि इसे पर्याप्त मेमोरी आवंटित नहीं किया गया है, इसके बदले में MetaClass उदाहरण कचरे के कारण होते हैं। अब कहते हैं कि उदाहरण के लिए यदि आप एक पाश है:

for(str in strings) { 
    println str.toUpperCase() 
} 

इस मामले हम String वर्ग पर एक विधि बुला रहे हैं में। यदि आप स्मृति पर कम चल रहे हैं तो क्या होगा कि लूप के प्रत्येक पुनरावृत्ति के लिए MetaClass कचरा इकट्ठा किया जाएगा और फिर अगले पुनरावृत्ति के लिए फिर से बनाया जाएगा। यह नाटकीय रूप से एक एप्लिकेशन को धीमा कर सकता है और जैसा कि आपने देखा है CPU को पिन किया जा रहा है। इस राज्य को आमतौर पर "मेटाक्लास मंथन" के रूप में जाना जाता है और यह संकेत है कि आपका एप्लिकेशन ढेर मेमोरी पर कम चल रहा है।

हैं ग्रूवी कचरा इन MetaClass उदाहरणों का संग्रह तो हाँ है कि मतलब होगा वहाँ ग्रूवी में एक स्मृति रिसाव है, लेकिन तथ्य यह है कि यह है कचरा इन कक्षाओं का संग्रह एक संकेत है सब कुछ ठीक है कि, के अलावा है नहीं था तथ्य यह है कि आपने पहली जगह में पर्याप्त ढेर स्मृति आवंटित नहीं की है। यही कारण है कि कहने के लिए आवेदन है कि सभी उपलब्ध स्मृति को खाने और पर्याप्त नहीं ग्रूवी सही ढंग से संचालित करने के लिए जा रहा है के दूसरे हिस्से में एक स्मृति रिसाव हो सकता है नहीं है।

अन्य जवाब आप का उल्लेख के रूप में, वर्ग उतराई और PermGen तोड़ मरोड़ वास्तव में अपनी स्मृति मुद्दों जब तक आप गतिशील कार्यावधि में कक्षाओं को पार्स हल के लिए कुछ भी नहीं पड़ेगा। गतिशील रूप से बनाए गए वर्गों को स्टोर करने के लिए JVM द्वारा PermGen स्पेस का उपयोग किया जाता है। ग्रूवी आप GroovyClassLoader.parseClass या GroovyShell.evaluate का उपयोग कर कार्यावधि में कक्षाएं संकलित करने के लिए अनुमति देता है। यदि आप निरंतर कक्षाओं को पार्स कर रहे हैं तो हां कक्षा को उतारने वाले झंडे जोड़ने से मदद मिल सकती है। भी यह पोस्ट देखें:

Locating code that is filling PermGen with dead Groovy code

हालांकि, एक ठेठ Grails आवेदन गतिशील कार्यावधि में कक्षाएं संकलन नहीं है और इसलिए PermGen और वर्ग उतराई सेटिंग्स फेरबदल वास्तव में कुछ भी हासिल नहीं होगा।

अगर आप -Xmx ध्वज का उपयोग करने के लिए पर्याप्त ढेर स्मृति आवंटित आप को सत्यापित करना चाहिए और अगर अधिक आवंटित नहीं।

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