java क्या गर्म तैनाती को एक "कठिन समस्या" है?




jvm hotdeploy (4)

काम पर, हमें " मेमोरियम से बाहर PermGen " अपवाद के साथ समस्या हो रही है, टीम लीड निर्णय लेने के साथ यह एक बग था जेवीएम - कोड के गर्म-तैनाती से संबंधित कुछ कई विवरणों को समझने के बिना, उन्होंने बताया कि गर्म तैनाती एक "मुश्किल समस्या" है, इतना मुश्किल है कि यहां तक ​​कि .NET अभी भी ऐसा नहीं करता है।

मुझे पक्षी की आंखों के दृश्य से गर्म तैनाती को समझाते हुए बहुत सारे लेख मिल गए, लेकिन तकनीकी विवरण की कमी हमेशा की गई। क्या कोई मुझे तकनीकी स्पष्टीकरण के लिए बता सकता है, और बताता है कि क्यों गर्म तैनाती "एक कठिन समस्या" है?


जब कोई वर्ग लोड होता है, तो कक्षा के बारे में विभिन्न स्थिर डेटा को PERGEN में संग्रहीत किया जाता है। जब तक इस कक्षा के उदाहरण के लिए एक जीवित संदर्भ मौजूद है, तब तक क्लास इंस्टेंस कचरा एकत्र नहीं किया जा सकता है।

मेरा मानना ​​है कि इस समस्या का एक हिस्सा क्या करना है या नहीं, जीसी को अनुसूचित जनजाति के पुराने वर्ग के उदाहरणों को हटा देना चाहिए या नहीं आमतौर पर, हर बार जब आप गर्म तैनात करते हैं, तो नए क्लास के उदाहरणों को पेर्मजेन मेमोरी पूल में जोड़ दिया जाता है, और पुराने लोग, अब अप्रयुक्त, आमतौर पर हटाए नहीं जाते हैं। डिफ़ॉल्ट रूप से, सूर्य JVMs PermGen में कचरा संग्रह नहीं चलाएगा, लेकिन यह वैकल्पिक "java" आदेश तर्कों के साथ सक्षम किया जा सकता है।

इसलिए, यदि आप पर्याप्त समय पर गर्म तैनात करते हैं, तो आप अंततः अपने PermGen अंतरिक्ष निकास करेंगे

यदि आपका वेब ऐप पूरी तरह से बंद नहीं होता है, तो अपरिवर्तित है - उदाहरण के लिए, यदि यह थ्रेड चल रहा है - तो उस वेब ऐप द्वारा उपयोग किए जाने वाले सभी क्लास इंस्टेंस को PermGen स्पेस में पिन किया जाएगा। आप redeploy और अब PermGen में लोड इन सभी वर्ग उदाहरणों की एक और पूरी प्रति है आप अपरिवर्तनीय हैं और थ्रेड, पेर्मजेन में क्लास के उदाहरणों का एक और सेट रखता है। आप प्रतियों के पूरे नेट सेट को पुनःनिर्धारित और लोड करते हैं ... और अंत में आपका पेर्मजेन भरता है।

आप कभी-कभी इसे ठीक कर सकते हैं:

  • PermGen और कक्षाओं में जीसी को सक्षम करने के लिए हाल ही में एक सूर्य JVM के लिए कमांड तर्क प्रदान करना वह है: -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
  • एक अलग जेवीएम का उपयोग करना जो निश्चित आकार के पेर्मेगेन को नियोजित नहीं करता है या जो भारित वर्गों पर जीसी करता है

लेकिन यह केवल तभी मदद करेगा जब आपकी वेब ऐप पूरी तरह से और साफ-साफ बंद हो जाए, उस वेब ऐप के लिए क्लास लोडर द्वारा लोड किए गए किसी भी कक्षा के किसी भी क्लास इंस्टॉलेशन में कोई भी लाइव संदर्भ न छोड़ें।

कक्षा लोडर लीक के कारण भी यह जरूरी समस्या को ठीक नहीं करेगा। (साथ ही कई मामलों में बहुत से इंटर्निंग स्ट्रिंग्स।)

अधिक के लिए निम्नलिखित लिंक देखें (दो बोल्ड वाले लोगों को समस्या का हिस्सा समझाने के लिए अच्छा चित्र है)


जावा का कौन सा संस्करण आप उपयोग कर रहे हैं? प्रारंभिक सूर्य 1.4.2 में कीड़े थीं, लेकिन यह लंबे समय तक काम कर रहा है।
बीटीडब्ल्यू, आप अपनी टीम लीड को कैसे ख़त्म करेंगे? क्या आप टीम का नेतृत्व कर रहे हैं?


सन जेवीएम में पेर्म गेन स्पेस तय हो गया है, और अंततः यह सभी उपभोग किया गया है (हां, जाहिरा तौर पर क्लासलोडर-संबंधित कोड में एक बग के कारण) => ओओएम।

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


सामान्य शब्दों में समस्या जावा का सुरक्षा मॉडल है जो वास्तव में इसे रोकने की कोशिश करता है कि पहले से लोड किया गया एक वर्ग फिर से लोड हो रहा है।

बेशक जावा शुरुआत के बाद से गतिशील वर्ग लोडिंग का समर्थन किया है, यह क्या मुश्किल है वर्ग फिर से लोड हो रहा है

यह हानिकारक (और एक अच्छे कारण के लिए) पर विचार किया गया था कि चल रहे जावा एप्लिकेशन को एक नए वर्ग के साथ दुर्भावनापूर्ण कोड के साथ इंजेक्ट किया गया था। उदाहरण के लिए, जावा से एक java.lang.String फटकारा कार्यान्वयन, कि स्ट्रिंग बनाने के बजाय, कुछ यादृच्छिक फाइल हील विधि लंबाई () को लागू करने से हटाता है

इसलिए, जिस तरह से जावा की कल्पना की गई थी (और मैं अनुमान लगा रहा था कि परिणामस्वरूप .net सीएलआर), क्योंकि यह जेवीएम में बहुत "प्रेरणा" थी, उसी वही वीएम को फिर से लोड करने के लिए एक पहले से भरी हुई कक्षा को रोकना था।

उन्होंने इस "फीचर" को ओवरराइड करने के लिए एक तंत्र की पेशकश की क्लासलोडर्स, लेकिन फिर क्लास लोडर्स के लिए नियम था, उन्हें नए वर्ग को लोड करने का प्रयास करने से पहले "पेरेंट" क्लासलोडर की अनुमति लेनी चाहिए, अगर माता-पिता पहले से ही कक्षा को लोड कर चुके हैं, तो नए क्लास को नजरअंदाज कर दिया गया है।

उदाहरण के लिए मैंने क्लासलोडर्स का उपयोग किया है जो एलडीएपी या आरडीबीएमएस से कक्षाएं लोड करते हैं

जावा एई के लिए आवेदन सर्वर मुख्य धारा बनने पर गर्म तैनाती की आवश्यकता बन जाती है (और इन प्रकार के बोझ से बचने के लिए वसंत जैसी सूक्ष्म कंटेनरों की आवश्यकता भी पैदा होती है)।

प्रत्येक कंपाइल ड्राइव किसी को भी पागल के बाद पूरे ऐप सर्वर को पुनः आरंभ।

तो ऐप सर्वर प्रदाता, गर्म परिनियोजन में मदद करने के लिए इस "कस्टम" वर्ग लोडर की पेशकश करें, और एक विन्यास फाइल का उपयोग करके, वह व्यवहार, उत्पादन में सेट होने पर अक्षम होना चाहिए। लेकिन व्यापार के लिए आप को विकास में कई मेमोरी का उपयोग करना पड़ता है। तो ऐसा करने का अच्छा तरीका हर 3-4 तैनाती को पुनरारंभ करना है।

यह उन अन्य भाषाओं के साथ नहीं होता है जो शुरुआत से लेकर अपनी कक्षाओं को लोड करने के लिए डिज़ाइन किए गए थे।

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

इन प्रकार के वातावरणों में व्यापार का तरीका निश्चित रूप से स्मृति और गति है

आशा है कि ये आपकी मदद करेगा।

संपादित करें

मैंने कुछ समय पहले इस उत्पाद को पाया है कि वादा करता है कि पुनः लोड जितना आसान हो उतना आसान है। जब मैंने पहली बार यह जवाब लिखा था, तब मुझे उस लिंक को याद नहीं था, और मैं करता हूं।

यह ज़ाइटरटाउरआराउंड से जावाआरबेल है





hotdeploy