जावा में स्थिर आवंटन - ढेर, ढेर और स्थायी पीढ़ी


117

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

  1. कक्षाएं (क्लासलोडर्स द्वारा लोड) ढेर पर एक विशेष क्षेत्र में जाती हैं: स्थायी पीढ़ी
  2. एक वर्ग से संबंधित सभी जानकारी जैसे कि कक्षा का नाम, ऑब्जेक्ट से जुड़ी वस्तुएं, जेवीएम द्वारा उपयोग की जाने वाली आंतरिक वस्तुएं (जैसे जावा / लैंग / ऑब्जेक्ट) और अनुकूलन जानकारी स्थायी पीढ़ी क्षेत्र में जाती है।
  3. सभी स्थिर सदस्य चर को स्थायी पीढ़ी क्षेत्र पर फिर से रखा जाता है।
  4. वस्तुएं एक अलग ढेर पर जाती हैं: युवा पीढ़ी
  5. प्रति कक्षा प्रत्येक विधि की केवल एक प्रति है, विधि स्थिर या गैर-स्थिर हो। उस प्रति को स्थायी सृजन क्षेत्र में रखा गया है। गैर-स्थिर तरीकों के लिए, सभी पैरामीटर और स्थानीय चर स्टैक पर जाते हैं - और जब भी उस पद्धति का एक ठोस आह्वान होता है, तो हमें इसके साथ एक नया स्टैक-फ्रेम मिलता है। मुझे यकीन नहीं है कि एक स्थिर विधि के स्थानीय चर कहाँ संग्रहीत किए जाते हैं। क्या वे स्थायी पीढ़ी के ढेर पर हैं? या सिर्फ उनका संदर्भ स्थायी पीढ़ी क्षेत्र में संग्रहीत है, और वास्तविक प्रति कहीं और है (कहां?)
  6. मैं भी अनिश्चित हूं कि रिटर्न का एक तरीका कहां जमा होता है।
  7. यदि ऑब्जेक्ट्स (युवा पीढ़ी में) को स्थैतिक सदस्य (स्थायी पीढ़ी में) का उपयोग करने की आवश्यकता होती है, तो उन्हें स्थैतिक सदस्य && का संदर्भ दिया जाता है और उन्हें रिटर्न मेमोरी के तरीके, आदि को स्टोर करने के लिए पर्याप्त मेमोरी स्पेस दिया जाता है।

इस के माध्यम से जाने के लिए धन्यवाद!

जवाबों:


152

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

यदि आप अपने उत्तरों की निश्चित पुष्टि चाहते हैं, तो आपको वास्तव में OpenJDK सोर्सकोड डाउनलोड करने की आवश्यकता है ... और स्रोत कोड को पढ़कर और समझकर अपना शोध करें । एसओ पर सवाल पूछना, या यादृच्छिक वेब लेखों के माध्यम से फंसना एक ध्वनि शैक्षिक अनुसंधान तकनीक नहीं है।

यह कहने के बाद ...

... मेरा प्रश्न सूर्य विशिष्ट है।

जिस समय यह प्रश्न पूछा गया था, सन माइक्रोसिस्टम्स का अस्तित्व समाप्त हो गया था। सवाल इसलिए ओरेकल विशिष्ट था। AFAIK, सभी वर्तमान (गैर-शोध) तृतीय-पक्ष JVM कार्यान्वयन या तो OpenJDK रिलीज़ के प्रत्यक्ष पोर्ट हैं या किसी अन्य Sun / Oracle रिलीज़ से उतारे गए हैं।

नीचे दिए गए जवाब ओरेकल हॉटस्पॉट और ओपनजेडके रिलीज पर लागू होते हैं, और शायद अधिकांश अन्य लोगों के लिए भी ... जिसमें ग्रेवालम भी शामिल है।

1) कक्षाएं (क्लास लोडर द्वारा लोड) ढेर पर एक विशेष क्षेत्र में जाती हैं: स्थायी पीढ़ी।

जावा 8 से पहले, हाँ।

Java 8 के रूप में, PermGen स्पेस को Metaspace से बदल दिया गया है। लोडेड और JIT- संकलित कक्षाएं अब वहाँ जाती हैं। PermGen अब मौजूद नहीं है।

2) एक वर्ग से संबंधित सभी जानकारी जैसे कि कक्षा का नाम, कक्षा से जुड़ी वस्तु सरणियाँ, जेवीएम (जैसे जावा / लैंग / ऑब्जेक्ट) द्वारा उपयोग की जाने वाली आंतरिक वस्तुएं और अनुकूलन जानकारी स्थायी पीढ़ी क्षेत्र में जाती है।

कमोबेश, हाँ। मुझे यकीन नहीं है कि आप उन चीजों में से कुछ से क्या मतलब है। मैं अनुमान लगा रहा हूं कि "JVM (जैसे जावा / लैंग / ऑब्जेक्ट) द्वारा उपयोग की जाने वाली आंतरिक वस्तुएं" का अर्थ है JVM- आंतरिक वर्ग विवरणकर्ता।

3) सभी स्थिर सदस्य चर को फिर से स्थायी पीढ़ी क्षेत्र पर रखा गया है।

चर खुद हां। ये चर (सभी जावा चर की तरह) या तो आदिम मान या वस्तु संदर्भ रखेंगे। हालाँकि, जब स्थिर सदस्य चर एक फ्रेम में होते हैं जो कि परमिट के ढेर में आवंटित किया जाता है, तो उन चर द्वारा निर्दिष्ट ऑब्जेक्ट / सरणियों को किसी भी ढेर में आवंटित किया जा सकता है ।

4) वस्तुएं एक अलग ढेर पर जाती हैं: युवा पीढ़ी

जरुरी नहीं। बड़ी वस्तुओं को सीधे कार्यकाल की पीढ़ी में आवंटित किया जा सकता है।

5) प्रति कक्षा प्रत्येक विधि की केवल एक प्रति है, विधि स्थिर या गैर-स्थिर हो। उस प्रति को स्थायी सृजन क्षेत्र में रखा गया है।

यह मानते हुए कि आप विधि के कोड का उल्लेख कर रहे हैं, तो AFAIK हाँ। यह हालांकि थोड़ा और अधिक जटिल हो सकता है। उदाहरण के लिए, कोड JVM के जीवन के दौरान अलग-अलग समय पर bytecode और / या मूल कोड रूपों में मौजूद हो सकता है।

... गैर-स्थिर तरीकों के लिए, सभी पैरामीटर और स्थानीय चर स्टैक पर जाते हैं - और जब भी उस विधि का एक ठोस आह्वान होता है, तो हमें इसके साथ एक नया स्टैक-फ्रेम मिलता है।

हाँ।

... मुझे यकीन नहीं है कि एक स्थिर विधि के स्थानीय चर कहाँ संग्रहीत किए जाते हैं। क्या वे स्थायी पीढ़ी के ढेर पर हैं? या सिर्फ उनका संदर्भ स्थायी पीढ़ी क्षेत्र में संग्रहीत है, और वास्तविक प्रति कहीं और है (कहां?)

नहीं, वे स्टैक पर संग्रहीत हैं, जैसे गैर-स्थिर तरीकों में स्थानीय चर।

6) मैं भी अनिश्चित हूं कि रिटर्न का एक तरीका कहां जमा होता है।

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

7) यदि ऑब्जेक्ट्स (युवा पीढ़ी में) स्थैतिक सदस्य (स्थायी पीढ़ी में) का उपयोग करने के लिए नीस करते हैं, तो उन्हें स्थैतिक सदस्य && का संदर्भ दिया जाता है और उन्हें वापसी प्रकार की विधि को स्टोर करने के लिए पर्याप्त मेमोरी स्पेस दिया जाता है, आदि। ।

यह गलत है (या कम से कम, आप अपने आप को स्पष्ट रूप से व्यक्त नहीं कर रहे हैं)।

यदि कुछ विधि एक स्थिर सदस्य चर का उपयोग करती है, तो उसे जो मिलता है वह या तो एक आदिम मूल्य या एक वस्तु संदर्भ है । यह एक मौजूदा (मौजूदा) स्थानीय चर या पैरामीटर को सौंपा जा सकता है, जो (मौजूदा) स्थिर या गैर-स्थैतिक सदस्य को सौंपा गया है, जो पहले से आवंटित सरणी के (मौजूदा) तत्व को सौंपा गया है, या बस इस्तेमाल किया और त्याग दिया गया है।

  • किसी भी मामले में एक संदर्भ या एक आदिम मूल्य रखने के लिए नए भंडारण को आवंटित करने की आवश्यकता नहीं है।

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

  • किसी भी मामले में किसी ऑब्जेक्ट / सरणी को किसी विधि द्वारा वापस रखने के लिए कॉलर द्वारा स्थान आवंटित करने की आवश्यकता नहीं होती है। जावा में, ऑब्जेक्ट और सरणियों को हमेशा पास-बाय-वैल्यू सिमेंटिक्स का उपयोग करके लौटाया जाता है ... लेकिन जो मान लौटाया जाता है वह एक ऑब्जेक्ट या एरे संदर्भ है।


अधिक जानकारी के लिए, कृपया इन संसाधनों का संदर्भ लें:

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