2012-11-07 13 views
16

इस प्रश्न को उत्पन्न करने के लिए एक सामान्य तरीके के लंबे समय के लिए सोचने के बाद (और एक खोजने में असफल) मैं इसे एक ठोस उदाहरण के रूप में पूछने जा रहा हूं:क्या होता है जब JVM रन टाइम के दौरान आवंटित करने के लिए स्मृति से बाहर चला जाता है?

मान लीजिए मेरे पास एक लिनक्स मशीन है जिसमें 1 जीबी है स्मृति की जो इसे प्रक्रियाओं को आवंटित कर सकती है (भौतिक और स्वैप योग 1 जीबी)।

मेरे पास मशीन पर मानक ओरेकल हॉटस्पॉट JVM संस्करण 7 स्थापित है। एक भी क्षण में, वहाँ पर्याप्त चल ऐसी है कि कि 1 जीबी की केवल 400 एमबी के लिए स्वतंत्र हैं कार्यक्रमों रहे हैं, और मैं निम्नलिखित JVM झंडे के साथ उस पल में एक जावा प्रोग्राम प्रारंभ करते हैं:

java -Xms256m -Xmx512m -jar myJar.jar 

क्या happends? :

ए। क्या JVM तुरंत शुरू करने में विफल रहता है क्योंकि यह सभी 512 एमबी मेमोरी आवंटित करने की कोशिश करेगा और असफल होगा (इस तथ्य के कारण कि इस समय पर्याप्त उपलब्ध स्मृति नहीं है)?

अगर JVM शुरू होता है:

अगर कुछ बिंदु पर चल जावा प्रक्रिया स्मृति के 400 से अधिक एमबी की आवश्यकता होगी (और अभी भी केवल 400 है कि क्या मौजूदा जावा प्रक्रिया पहले से ही इस्तेमाल किया गया है की तुलना में मुक्त अन्य है स्मृति की एमबी है), क्या होगा:

बी जावा प्रक्रिया आउटऑफमेमरोइरर के साथ विफल हो जाएगी?

सी। क्या यह किसी अन्य (मानक) त्रुटि के साथ विफल हो जाएगा?

डी। क्या यह अनिर्धारित व्यवहार है?

+1

मुझे विश्वास है (बी), हालांकि अगर केवल 200 एमबी (एक्सएमएस से कम) उपलब्ध था तो विकल्प ए – Scorpion

उत्तर

9

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

+0

धन्यवाद। लेकिन फिर, क्या मैं मान सकता हूं कि यदि मैं एक्सएमएस * के लिए एक मान * पास करता हूं जो वर्तमान में मुफ्त मेमोरी आकार से बड़ा है (यानी मेरे एक्सपैम्पल में, क्या होगा यदि मैंने एक्सएमएस को 500 मीटर में बदल दिया) तो जेवीएम शुरू करने में असफल रहेगा? –

+1

यहां एक नज़र डालें: http://stackoverflow.com/questions/3648454/what-happens-if-you-specify-max-heap-size-greater-than-available-ram – Polygnome

+0

लिंक के लिए धन्यवाद, वह प्रश्न साफ़ करता है मेरे कुछ मुद्दों पर, लेकिन यह केवल सिस्टम पर वास्तविक कुल स्मृति को छोड़कर एक्सएमएक्स को संदर्भित करता है। मैं सोच रहा था कि एक्सएमएक्स मूल्य वर्तमान में उपलब्ध (मुक्त) मेमोरी (भौतिक और स्वैप) को कैसे हटाता है (लेकिन सिस्टम की कुल भौतिक रूप से स्थापित स्मृति को न तोड़ता है और न ही यह 32 बिट मेमोरी सीमा का उल्लंघन करता है) –

2

OutOfMemroyErrorहोगा "जब जावा वर्चुअल मशीन किसी ऑब्जेक्ट को आवंटित नहीं कर सकती है क्योंकि यह स्मृति से बाहर है, और कचरा कलेक्टर द्वारा कोई और स्मृति उपलब्ध नहीं कराई जा सकती है।"

तो, संक्षेप में, "बी जावा प्रक्रिया एक OutOfMemroyError के साथ विफल"।

+0

उत्तर के लिए धन्यवाद। क्या मुझे लगता है कि यह सभी हॉटस्पॉट कार्यान्वयन के लिए सच है (यानी सभी ऑपरेटिंग सिस्टम पर जिसके लिए हॉटस्पॉट जेवीएम उपलब्ध है)? –

6

मान लीजिए कि मेरे पास एक लिनक्स मशीन है जिसमें 1 जीबी मेमोरी है जो इसे प्रक्रियाओं (भौतिक और स्वैप योग 1 जीबी) आवंटित कर सकती है।

मेरी पहली प्रतिक्रिया तब तक होगी जब तक कि आप किसी फोन के बारे में बात नहीं कर रहे हैं, मुझे और अधिक स्मृति मिल जाएगी। आप $ 100 से कम के लिए 16 जीबी (बी = बिट, बी = बाइट) खरीद सकते हैं।

क्या JVM तुरंत शुरू करने में विफल रहता है क्योंकि यह सभी 512 एमबी मेमोरी आवंटित करने की कोशिश करेगा और असफल होगा (इस तथ्य के कारण कि इस समय पर्याप्त उपलब्ध स्मृति नहीं है)?

यह तब हो सकता है जब आपके सिस्टम में 512 एमबी (प्लस कुछ ओवरहेड) न हो क्योंकि यह स्टार्टअप पर ढेर के लिए उपयोग की जाने वाली निरंतर वर्चुअल मेमोरी आवंटित करता है।

यदि आपके पास 550 एमबी मुक्त है, तो भी प्रोग्राम शुरू करने में असफल हो सकता है क्योंकि इसे केवल ढेर से अधिक लोड करने की आवश्यकता है।

जावा प्रक्रिया आउटऑफमेमरी एरर के साथ विफल हो जाएगी?

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

क्या यह किसी अन्य (मानक) त्रुटि के साथ विफल हो जाएगा?

यह संभव है यदि प्रोग्राम शुरू होने के बाद आप स्वैप स्पेस से बाहर हो जाएं। यह दुर्लभ है और केवल गंभीर रूप से अधिभारित मशीन पर होता है। जो मैंने देखा है वह स्मृति स्तर आवंटित करने के लिए निम्न स्तर की ओएस विफलता के कारण JVM क्रैश है।

Java 6 Update 25 VM crash: insufficient memory

+0

+1 विशेष रूप से अपरिभाषित व्यवहार के बारे में अंतिम टिप्पणी के लिए +1। –

+1

@ पीटर - मुझे पूरी तरह से यकीन नहीं है, लेकिन मुझे विश्वास है कि सिस्टम में '-xmx' के साथ निर्दिष्ट की तुलना में कम स्मृति है, तो JVM बस अधिकतम उपलब्ध पर सेट हो जाएगा, और तुरंत क्रैश नहीं होगा। --- मुझे नहीं पता कि यह वही है जो '-xms' पर लागू होता है। शायद ऩही।--- मुझे यह भी लगता है कि उत्तर अधिक सामान्यीकृत होना चाहिए, और '512 एमबी' उदाहरण के आसपास कम केंद्रित होना चाहिए, ताकि भविष्य में यह प्रश्न अन्य समुदाय सदस्यों के लिए स्पष्ट हो सके। उत्कृष्ट जवाब के लिए --- +1। विशेष रूप से अंतिम खंड। – XenoRo

+1

-xms सेटिंग इससे कोई फर्क नहीं पड़ता कि यह शुरू होगा या नहीं। यह जीसी को इस आकार में आसानी से बढ़ने के लिए कहता है। नोट: एक "हैलो वर्ल्ड" प्रोग्राम न्यूनतम आकार का उपयोग नहीं करेगा क्योंकि आप इसे न्यूनतम के रूप में सेट करते हैं। –

1

जेवीएम प्रक्रिया वर्चुअल मेमोरी में चलती है, इसलिए चल रही अन्य प्रक्रियाओं के आवंटन का सवाल प्रासंगिक है, लेकिन पूरी तरह से निर्धारक नहीं है।

जब JVM अधिक स्मृति आवंटित नहीं कर सकता (जो भी कारण के लिए), प्रक्रिया ही समाप्त नहीं होता है, बल्कि भीतर JVM OutOfMemoryErrorफेंकने शुरू होता है, लेकिन JVM के लिए बाहरी नहीं। दूसरे शब्दों में, JVM चल रहा है, लेकिन JVM के भीतर चल रहे प्रोग्राम आमतौर पर विफल हो जाएंगे, क्योंकि अधिकांश कम स्मृति स्थितियों को पर्याप्त रूप से संभाल नहीं पाते हैं। इस काफी आम मामले में, जब प्रोग्राम त्रुटि को संभालने के लिए कुछ भी नहीं करता है, तो JVM प्रोग्राम को समाप्त कर देगा और बाहर निकल जाएगा। आखिरकार, यह स्मृति आवंटन से है, लेकिन सीधे नहीं। कोड के एक टुकड़े के लिए खुद को कम स्मृति स्थिति के तहत वापस स्केल करना संभव है और चलना जारी है।

और अन्य ने इंगित किया है, कभी-कभी ऐसा होता है कि JVM स्वयं कम स्मृति को अच्छी तरह से संभाल नहीं पाता है, लेकिन यह एक बहुत चरम स्थिति है।

2

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

यदि आप JVM चला सकते हैं, तो आप -एक्सएमएक्स के साथ हीप स्पेस पर सीमा निर्दिष्ट कर सकते हैं। इसका मतलब यह नहीं है कि सभी ढेर जेवीएम द्वारा शुरू किए जाएंगे - यह केवल एक आंतरिक सीमा है। यदि JVM ढेर स्थान को बढ़ाना चाहेगा, लेकिन पर्याप्त स्मृति नहीं है, या आपको -Xmx द्वारा निर्दिष्ट की तुलना में अधिक ढेर की आवश्यकता है, तो आप वर्तमान में जावा प्रोग्राम चलाने में OutOfMemoryError प्राप्त करेंगे।

एक बहुत ही चरम स्थिति में, आप जेवीएम चलते समय मुफ्त मेमोरी से बाहर निकल सकते हैं, और साथ ही साथ JVM को अपने आंतरिक ऑपरेशन (ढेर स्थान नहीं) के लिए अधिक मेमोरी की आवश्यकता होती है - फिर JVM आपको बताता है अधिक स्मृति की आवश्यकता है, लेकिन कोई भी नहीं मिल सका, और समाप्त हो सकता है, या यह पूरी तरह दुर्घटनाग्रस्त हो जाएगा।

+0

मेरे पास है प्रक्रिया जो xms और xmx समान है, जबकि मेरी प्रक्रिया कभी-कभी मेरे टेस्ट एनवी में दुर्घटनाग्रस्त हो जाती है क्योंकि स्मृति बहुत अधिक नहीं छोड़ी जाती है, मुझे लगता है कि कम स्मृति मेरी प्रगति को मारता है, लेकिन मुझे ओम त्रुटि या ओम हीप डंप फ़ाइल नहीं मिलती है (मैं बारी करता हूं विकल्प पर)। क्या मैं सही मानता हूं या नहीं, अगर मैं चिल्लाता हूं कि ओओएम फाइल क्यों नहीं है? – Jaskey

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

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