2016-04-27 10 views
17

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

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

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

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

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

+1

आपको यह जवाब मिल सकता है [http://stackoverflow.com/a/25318740/2032064) – Mifeet

उत्तर

4

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

Further reading

तो आपके सवालों के जवाब:

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

हां।

यदि हां, तो वास्तव में ढेर स्मृति पर कहां है?

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

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

ऐसा नहीं है।

के रूप में आप की तरह जब तक आप अपने JVM स्मृति बाहर maxed है चाहते हैं और मिल आप के रूप में कई बना सकते हैं

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

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

ऊपर की

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

+0

इंटरैस्टिंग, साथ ही, ये अच्छे उत्तर हैं, यह JVM के लिए एक आंतरिक विनिर्देश है। उपर्युक्त में से कोई भी किसी भी समय बदल सकता है। यह नहीं होना चाहिए, और इससे कोई फर्क नहीं पड़ता कि कैसे * JVM अपना काम करता है। JVM को तय करें कि अपने संसाधनों का प्रबंधन कैसे करें। – markspace

+0

हाँ, लेकिन इसका मतलब यह नहीं है कि HotSpot कैसे करता है यह दिलचस्प नहीं है। – Mifeet

+0

@markspace धन्यवाद, विशिष्ट 'JVM' के साथ मेरा उत्तर अपडेट किया गया है, लेकिन क्या आपको सच में लगता है कि' JVM 'है जो इन मामलों पर अलग-अलग कार्य करता है? – Daniel

30

धागे के ढेर के बारे में कुछ चीजें हैं जो Java specification हमें बताती हैं। अन्य चीजों के अलावा:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

और क्योंकि एक छवि एक हजार शब्दों के लायक है, यहां से James BloomJava memory


एक अब आपके कुछ प्रश्नों का जवाब दे रहा है:

JVM कैसे जानता है कि कैसे हो सकता है धागे होगा बनाया जाना चाहिए?

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

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

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

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

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

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

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

+1

खैर, इनमें से अधिकांश को [JVM spec] (https://docs.oracle.com/javase/specs/jvms/se8/html/) में परिभाषित किया गया है, नहीं? AFAIK, जीसी वह क्षेत्र है जो spec से बाहर छोड़ा गया है। –

+1

आप सही हैं, मैंने सोचा था कि जेवीएम स्पेक में और भी कुछ है। इस बीच मैंने अपना जवाब अपडेट कर लिया है। – Mifeet

+0

तो यदि मेरे पास 512 एमबी ढेर है, और यदि मैं 1000 धागे बना रहा हूं (जाहिर है यह 512 एमबी से बड़ा है), क्या यह मेरे ढेर की याददाश्त पर कब्जा करता है और इस प्रकार ओओएम अपवाद या ओएस में अतिरिक्त मेमोरी स्पेस है? – Jaskey