जेवीएम पर ढेर का आकार क्यों तय किया गया है?


20

क्या कोई मुझे समझा सकता है कि जेवीएम (मैंने बहुत अधिक जांच क्यों नहीं की, लेकिन मैंने कभी ऐसा नहीं देखा है कि यह उस तरह से नहीं हुआ) एक निश्चित हीप आकार पर चलने की आवश्यकता है? मुझे पता है कि एक साधारण सन्निहित ढेर पर इसे लागू करना आसान है, लेकिन सूर्य जेवीएम अब एक दशक से अधिक पुराना है, इसलिए मैं उनसे यह सुधार करने का समय चाहता हूं।

स्टार्टअप के समय में अपने प्रोग्राम के अधिकतम मेमोरी साइज़ को परिभाषित करने की आवश्यकता होती है, ऐसा करने के लिए 1960 की बात लगती है, और फिर OS वर्चुअल मेमोरी मैनेजमेंट के साथ खराब इंटरैक्शन (GC पुनर्प्राप्त डेटा स्वैप आउट), यह निर्धारित करने में असमर्थता है कि जावा प्रक्रिया कितनी मेमोरी है। वास्तव में ओएस की ओर से उपयोग करते हुए, वीएम स्पेस की बड़ी मात्रा में बर्बाद हुई (मुझे पता है, आप अपने फैंसी 48 बिट मशीनों पर ध्यान नहीं देते ...))। मैं यह भी अनुमान लगाता हूं कि JVM (EE एप्लिकेशन सर्वर, OSGi) के अंदर छोटे ऑपरेटिंग सिस्टम के निर्माण के विभिन्न दु: खद प्रयास कम से कम आंशिक रूप से इस परिस्थिति को दोष देने के लिए हैं, क्योंकि सिस्टम पर कई जावा प्रक्रियाओं को चलाने से व्यर्थ संसाधनों का नुकसान होता है जो आपको करना पड़ता है उनमें से प्रत्येक को वह चरम पर उपयोग करने की स्मृति दे सकते हैं।

हैरानी की बात है कि, Google ने इस पर नाराजगी के तूफानों का उत्पादन नहीं किया, जिसकी मुझे उम्मीद थी, लेकिन वे शायद लाखों लोगों को निश्चित हीप आकार के बारे में पता लगाने और केवल एक तथ्य के लिए इसे स्वीकार करने के तहत दफन हो गए।


ईई एप्लिकेशन सर्वर का डिज़ाइन इस "परिस्थिति" के बिना भी सही अर्थों में समझ में आता है क्योंकि जेवीएम को खुद कुछ स्थान की आवश्यकता होती है, और थ्रेड के बीच स्विच करना प्रक्रियाओं के बीच स्विच करने की तुलना में सस्ता है - यह उन चीजों में से एक है जो 90 के दशक के अंत में जावा को बड़ा बना दिया था।
माइकल बोर्गवर्ड

यह एक प्रकार है, और मुझे आश्चर्य है कि आपने कितना सोचा है। उदाहरण के लिए, यदि आपके पास ढेर सीमा नहीं थी, तो GC / स्वैप इंटरैक्शन कैसे बदलेगा? वीएम स्पेस कैसे बर्बाद होता है? आपको अपना 2 / 3Gb स्पेस मिलता है चाहे आप इसका उपयोग करें या नहीं, और यदि आप उस स्थान की सीमा को आगे बढ़ा रहे हैं तो इससे कोई फर्क नहीं पड़ता कि आपको एक निश्चित या अस्थायी ढेर मिला है या नहीं। उस मामले के लिए, कई जेवीएम स्वैप के अलावा कुछ भी कैसे बर्बाद करते हैं (जिसे मशीन के उद्देश्य के लिए उचित रूप से कॉन्फ़िगर किया जाना चाहिए)?
kdgregory

2
यह एक प्रकार का शेख़ी है, लेकिन यह दैनिक अनुभव के वर्षों के लेखन और जावा आधारित प्लेटफ़ॉर्म को संचालित करने के द्वारा सूचित किया जाता है। यदि आप स्वैप नहीं करते हैं (क्योंकि यह आपके सिस्टम को 20 मिनट तक अनुत्तरदायी बना देगा, जब तक कि रनवे प्रक्रिया आवंटित करने के लिए अंतरिक्ष से बाहर नहीं निकलती है) और स्थिरता कारणों के लिए मेमोरी ओवरकमाइट बंद हो जाती है (पीड़ितों को लेने के लिए ओओएम हत्यारा बहुत अच्छा नहीं है) ), आप वीएम स्पेस के बारे में परवाह करते हैं, और नीचे के लोग क्या लागू कर रहे हैं इसके विपरीत, एक एक्सएम वीएम के साथ -Xmx2048m लॉन्च करने से तुरंत एक चर के लिए एक प्रोग्राम के लिए 2 जीबी वर्चुअल मेमोरी (कम से कम मेरे सन जेवीएम लिनक्स पर) आवंटित होगी।
थीमल 17

बहुत बढ़िया सवाल। एक ही बात सोच रहा था। लेकिन q और उत्तर में प्रस्तुत किए गए "तथ्यों" में से कौन सा उत्तर सही है?
मार्टिन बा

प्रतिक्रियाओं के लिए आप देख रहे थे, बस सूरज बग ट्रैकर के साथ mosey ... जैसे यहाँ , यहाँ और यहाँ । उन लोगों को पढ़ें और क्रोध को महसूस करें :)
मूल

जवाबों:


23

तुम गलत हो। JVMs का ढेर का आकार तय नहीं है, केवल सीमाबद्ध है:

  • -Xmx अधिकतम ढेर स्मृति आकार सेट करता है
  • -Xms न्यूनतम हीप मेमोरी साइज़ सेट करता है

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


9
कोई भी मिनट धीमी गति से स्टार्टअप से बचने के लिए डिफ़ॉल्ट नहीं होता है जब बहुत अधिक बार-बार ढेर बढ़ने के परिणामस्वरूप आवंटित करने की आवश्यकता होती है, पेजिंग शारीरिक रूप से बाहर चलने से
निपटेगी

@ratchetfreak जो मेरा दूसरा अनुमान था ;-)
user281377

@ user281377 अगर यह मामला है, तो अधिकतम # मेमोरी मेमोरी के बिना C # कैसे ठीक चल सकता है?
सेमी

cmorse: मैं केवल अनुमान लगा सकता हूं। शायद जावा को बड़े सर्वरों पर लक्षित किया जाता है, जहां कई एप्लिकेशन संसाधनों को साझा करते हैं और कड़ाई से लागू की गई सीमाएं वांछनीय हैं, जबकि .net को पीसी और छोटे, अधिक समर्पित सर्वरों के लिए बनाया गया है।
user281377

@ user281377: मैंने जिन जावा अनुप्रयोगों का उपयोग किया है, वे ढेर स्थान से बाहर निकलते हैं, आमतौर पर इसे बहुत खराब तरीके से संभालते हैं, आमतौर पर बस दुर्घटनाग्रस्त हो जाते हैं या इसके बाद बहुत खराब हो जाते हैं। और ASP.net बड़े और छोटे दोनों सर्वरों पर ठीक चलता है। मैं वास्तव में क्या नहीं है क्यों डिफ़ॉल्ट रूप से है, जावा इस सीमा को लागू करता है। मुझे उनके निर्णय के पीछे के तर्क को सुनना अच्छा लगेगा ... मुझे यकीन है कि उनके पास एक अच्छा कारण था।
सेमी cmorse

6

मुझे लगता है कि उत्तर का जावा की विरासत के साथ कुछ करना है। यह मूल रूप से एम्बेडेड सिस्टम के लिए उपयोग की जाने वाली भाषा के रूप में डिज़ाइन किया गया था, जहां स्पष्ट रूप से संसाधनों की कमी होती है और आप प्रक्रियाओं को केवल जो कुछ भी उपलब्ध नहीं है, नहीं चाहते हैं। यह सिस्टम प्रशासन के साथ भी मदद करता है, क्योंकि यदि आप संसाधन सीमा निर्धारित कर सकते हैं तो सर्वर पर संसाधनों का प्रावधान करना आसान हो जाता है। मैं देखता हूं कि नवीनतम JVMs कई गैर-निरंतर ढेर का उपयोग करते हैं, हालांकि निश्चित रूप से यह सभी आपके कोड के लिए एक हीप के रूप में दिखाई देता है।

(एफडब्ल्यूआईडब्ल्यू, आपको एप्पल के डार्विन मैकओएस संस्करणों के तहत एक कार्यक्रम की स्मृति आवश्यकताओं को निर्दिष्ट करना था [वैसे भी सिस्टम 7 तक, जो कि मैंने पिछले एक इस्तेमाल किया था], जो कि 80 के दशक में अच्छी तरह से था।)


1
+1 - (1) होने के लिए एकमात्र उत्तर जो वास्तव में प्रश्न को संबोधित करता है, और (2) प्रशंसनीय है।
kdgregory

2

आपको जीसी को यह बताने के लिए कुछ तंत्र देने की आवश्यकता है कि कब चलना है, या आपका प्रोग्राम पूरे वर्चुअल मेमोरी स्पेस को भर देगा। जीसी को ट्रिगर करने के कई वैकल्पिक तरीके हैं: बीता हुआ समय, आवंटन की संख्या, असाइनमेंट की संख्या, शायद अन्य जो मैं अभी नहीं सोच सकता। IMO उनमें से कोई भी नहीं है जितना कि बस एक मेमोरी सीमा सेट करना और जीसी को चलाना जब आवंटित स्थान उस सीमा को हिट करता है।

कुंजी सही सीमा निर्धारित करना है । मैं -msइस रूप में देखता हूं कि "यह है कि मेरे ऐप को कितनी मेमोरी की आवश्यकता है," और -mx"के रूप में इसे इस राशि से अधिक नहीं होना चाहिए।" एक उत्पादन परिनियोजन में, दोनों समान नहीं होने पर पास होना चाहिए, और वे वास्तविक, मापा आवश्यकताओं पर आधारित होना चाहिए।

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

केवल एक चीज जो एक बड़े ढेर को "बर्बाद" कर सकती है वह है स्वैप स्पेस, क्योंकि सभी राइट सेगमेंट को स्वैप से प्रतिबद्धता की आवश्यकता होती है। लेकिन यह सिस्टम डिजाइन का हिस्सा है: यदि आप एक ही बॉक्स पर बहुत सारे जेवीएम चलाना चाहते हैं, तो या तो अपना स्वैप बढ़ाएं या उनके ढेर आवंटन को कम करें। यदि वे थ्रेशिंग शुरू करते हैं, तो आप सिस्टम के साथ बहुत अधिक करने की कोशिश कर रहे हैं; अधिक मेमोरी खरीदें (और यदि आप अभी भी 32-बिट प्रोसेसर चला रहे हैं, तो नया बॉक्स खरीदें)।


1
लेकिन जीसी को चलाने के लिए थ्रेशोल्ड को एक निश्चित सीमा के साथ कुछ भी नहीं करना पड़ता है जो प्रोग्राम द्वारा कुल मेमोरी उपयोग से अधिक नहीं हो सकता है। (वास्तव में यह शायद नहीं होना चाहिए; यदि आपके पास एक बड़ा ढेर है और आप केवल जीसी हो सकते हैं जब यह पूर्ण हो, तो आपके पास आवश्यक रूप से दुर्लभ-लेकिन-लंबी अवधि के जीसी होते हैं)। जेनरल कचरा संग्रहण देखें।
बेन

@ - हाँ, तुम सही हो। और मेरा दूसरा वाक्य बताता है कि विकल्प हैं। हालांकि, मैं इस बात से सहमत नहीं हूं कि एक निश्चित आकार का ढेर सामान्य मामले में जीसी को प्रबंधित करने का गलत तरीका है। एक ठीक से ट्यून किए गए JVM "सही" हीप आकार का उपयोग करता है; जब जेवीएम ठीक से ट्यून नहीं किया गया था तो मेरे अनुभव में लंबे जीसी पॉज होते हैं। और अक्सर "सही" ढेर का आकार आपके विचार से बहुत छोटा होता है।
kdgregory

-2

जैसा कि user281377 कहता है, आप केवल एक ऊपरी सीमा निर्दिष्ट करते हैं कि आपकी प्रक्रिया कितनी मेमोरी का उपभोग कर सकती है। बेशक, एप्लिकेशन को केवल उस स्थान को हथियाना होगा जिसकी उसे जरूरत है।

क्या कोई डिफ़ॉल्ट ऊपरी सीमा मौजूद होनी चाहिए या नहीं यह एक और सवाल है, दोनों समर्थक और गर्भनिरोधक के साथ।

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