java - जावा(JVM) प्रत्येक थ्रेड के लिए स्टैक कैसे आवंटित करता है




memory (2)

जेवीएम सिर्फ ढेर की तुलना में अधिक मेमोरी का उपयोग करता है। उदाहरण के लिए जावा विधि, थ्रेड स्टैक्स और देशी हैंडल को ढेर से अलग मेमोरी, साथ ही साथ जेवीएम आंतरिक डेटा संरचनाओं में आवंटित किया जाता है।

(Source)

तो आपके सवालों का जवाब देने के लिए:

क्या जावा बनाते समय प्रत्येक थ्रेड के लिए एक स्टैक बनाता है?

हाँ।

यदि हां, तो मेमोरी पर स्टैक कहां है?

जेवीएम में मेमोरी आवंटित की, लेकिन ढेर पर नहीं।

यदि हां, तो जेवीएम कैसे जानता है कि धागे कैसे बनाए जा सकते हैं?

यह नहीं है

जब तक आप अपनी JVM मेमोरी को अधिकतम नहीं कर लेते और प्राप्त कर सकते हैं, तब तक आप इसे बना सकते हैं

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

संपादित करें:

उपरोक्त सभी Jrockit JVM को संदर्भित करता है, हालांकि मुझे विश्वास करना मुश्किल है कि अन्य JVM ऐसे मूलभूत मुद्दों पर अलग होंगे।

एक जावा एप्लिकेशन सभी थ्रेड्स के लिए एक ढेर के साथ शुरू होता है। प्रत्येक धागे का अपना ढेर है।

जब एक जावा एप्लिकेशन शुरू किया जाता है, तो हम ढेर के आकार को नियंत्रित करने के लिए JVM विकल्प -Xms और -Xss का उपयोग करते हैं ताकि स्टैक के आकार को नियंत्रित किया जा सके।

मेरी समझ यह है कि बनाया जा रहा ढेर JVM की एक "प्रबंधित" स्मृति बन जाता है और बनाई जा रही सभी वस्तु को वहां रखा जाता है।

लेकिन स्टैक निर्माण कैसे काम करता है? क्या जावा बनाते समय प्रत्येक थ्रेड के लिए एक स्टैक बनाता है? यदि हां, तो मेमोरी पर स्टैक कहां है? यह निश्चित रूप से "प्रबंधित" ढेर में नहीं है।

क्या जेवीएम देशी मेमोरी से स्टैक बनाता है या स्टैक के लिए प्रबंधित मेमोरी क्षेत्र के एक खंड को पूर्व-आवंटित करता है? यदि हां, तो जेवीएम कैसे जानता है कि धागे कैसे बनाए जा सकते हैं?


थ्रेड स्टैक के बारे में कुछ चीजें हैं जो जावा विनिर्देश हमें बताता है। अन्य बातों के अलावा:

  • प्रत्येक जावा वर्चुअल मशीन थ्रेड में एक निजी जावा वर्चुअल मशीन स्टैक होता है, जिसे थ्रेड के रूप में उसी समय बनाया जाता है।

  • क्योंकि जावा वर्चुअल मशीन स्टैक को कभी भी पुश और पॉप फ्रेम को छोड़कर सीधे हेरफेर नहीं किया जाता है, फ्रेम को आवंटित किया जा सकता है। जावा वर्चुअल मशीन स्टैक के लिए मेमोरी को सन्निहित होने की आवश्यकता नहीं है।

  • विशिष्टता जावा वर्चुअल मशीन स्टैक को या तो एक निश्चित आकार की हो या कम्प्यूटेशन द्वारा आवश्यक रूप से विस्तार और अनुबंध करने की अनुमति देती है।

अब, यदि हम हॉटस्पॉट जैसे जेवीएम कार्यान्वयन पर ध्यान केंद्रित करते हैं, तो हम कुछ और जानकारी प्राप्त कर सकते हैं। यहाँ कुछ तथ्य दिए गए हैं जिन्हें मैंने विभिन्न स्रोतों से एकत्र किया है:

  • किसी थ्रेड के लिए हॉटस्पॉट में न्यूनतम स्टैक का आकार निश्चित प्रतीत होता है। यह वही है जो aforementioned -Xss विकल्प के लिए है। (Source)

जावा एसई 6 में, स्पार्क पर डिफ़ॉल्ट 32-बिट वीएम में 512k और 64-बिट वीएम में 1024k है। ... -Xss ऑप्शन के साथ दौड़कर आप अपने स्टैक साइज को कम कर सकते हैं। ... 64k प्रति थ्रेड अनुमति दी गई कम से कम स्टैक स्पेस की मात्रा है।

  • JRockit ढेर से अलग स्मृति को आवंटित करता है जहां ढेर स्थित हैं। (Source)

ध्यान दें कि JVM केवल ढेर की तुलना में अधिक मेमोरी का उपयोग करता है। उदाहरण के लिए जावा विधि, थ्रेड स्टैक्स और देशी हैंडल को ढेर से अलग मेमोरी, साथ ही साथ जेवीएम आंतरिक डेटा संरचनाओं में आवंटित किया जाता है।

  • हॉटस्पॉट में एक जावा थ्रेड और एक देशी ओएस थ्रेड के बीच एक सीधा मानचित्रण है। (Source)

  • लेकिन हॉटस्पॉट में जावा थ्रेड स्टैक सॉफ्टवेयर प्रबंधित है, यह ओएस देशी थ्रेड स्टैक नहीं है। (Source)

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

  • JVM भी देशी तरीकों और JVM रनटाइम कॉल (जैसे वर्ग लोडिंग) के लिए एक ही जावा थ्रेड स्टैक का उपयोग करता है। (Source)

  • दिलचस्प है, यहां तक ​​कि आवंटित वस्तुओं को प्रदर्शन अनुकूलन के रूप में ढेर के बजाय कभी-कभी ढेर पर स्थित किया जा सकता है। (Source)

जेवीएम बच निकलने के विश्लेषण नामक एक तकनीक का उपयोग कर सकते हैं, जिसके द्वारा वे बता सकते हैं कि कुछ वस्तुएं अपने पूरे जीवनकाल के लिए एक ही धागे तक सीमित रहती हैं, और यह जीवनकाल किसी दिए गए स्टैक फ्रेम के जीवनकाल से घिरा होता है। ढेर के बजाय ऐसी वस्तुओं को ढेर पर सुरक्षित रूप से आवंटित किया जा सकता है।

और क्योंकि एक छवि एक हजार शब्दों के लायक है, यहां (Source) से एक है

अब आपके कुछ सवालों के जवाब दे रहे हैं:

जेवीएम कैसे जानता है कि धागे कैसे बनाए जा सकते हैं?

यह नहीं है धागे की एक चर संख्या बनाकर विरोधाभास से आसानी से साबित किया जा सकता है। यह थ्रेड्स की अधिकतम संख्या और प्रत्येक थ्रेड के स्टैक आकार के बारे में कुछ धारणाएँ बनाता है। इसलिए, यदि आप बहुत सारे थ्रेड आवंटित करते हैं, तो आप मेमोरी से बाहर निकल सकते हैं (मतलब ढेर मेमोरी नहीं!)।

क्या जावा बनाते समय प्रत्येक थ्रेड के लिए एक स्टैक बनाता है?

जैसा कि पहले उल्लेख किया गया है, प्रत्येक जावा वर्चुअल मशीन थ्रेड में एक निजी जावा वर्चुअल मशीन स्टैक होता है, जिसे थ्रेड के रूप में उसी समय बनाया जाता है। (स्रोत)

यदि हां, तो मेमोरी पर स्टैक कहां है? यह निश्चित रूप से "प्रबंधित" ढेर में नहीं है।

जैसा कि ऊपर कहा गया है, जावा विनिर्देश ढेर मेमोरी को तकनीकी रूप से बोलने वाले ढेर पर संग्रहीत करने की अनुमति देता है। लेकिन कम से कम JRockit JVM मेमोरी के एक अलग हिस्से का उपयोग करता है।

क्या जेवीएम देशी मेमोरी से स्टैक बनाता है या स्टैक के लिए प्रबंधित मेमोरी क्षेत्र के एक खंड को पूर्व-आवंटित करता है?

स्टैक JVM प्रबंधित है क्योंकि जावा विनिर्देश निर्दिष्ट करता है कि इसे कैसे व्यवहार करना चाहिए: एक जावा वर्चुअल मशीन स्टैक स्टोर फ्रेम (। 6.6)। एक जावा वर्चुअल मशीन स्टैक एक पारंपरिक भाषा के ढेर के अनुरूप है । एक अपवाद native तरीकों के लिए प्रयुक्त मूल विधि के ढेर हैं। इसके बारे में फिर से विनिर्देश में







jvm