2008-11-26 13 views
10

कक्षा में निम्न ऑब्जेक्ट को तत्काल करने पर स्मृति में क्या होता है?जावा ऑब्जेक्ट्स के लिए स्मृति आवंटन प्रक्रिया में चरण

public class SomeObject{ 

    private String strSomeProperty; 

    public SomeObject(String strSomeProperty){ 
     this.strSomeProperty = strSomeProperty; 
    } 
    public void setSomeProperty(String strSomeProperty){ 
     this.strSomeProperty = strSomeProperty; 
    } 
    public String getSomeProperty(){ 
     return this.strSomeProperty; 
    } 
} 

वर्ग SomeClass1 में:

SomeObject so1 = new SomeObject("some property value"); 

कक्षा में SomeClass2:

SomeObject so2 = new SomeObject("another property value"); 

स्मृति नव instantiated वस्तु और उसके गुणों के लिए आवंटित कैसे की जाती है? इसके माध्यम से

उत्तर

9

आइए कदम:

SomeObject so1 = new SomeObject("some property value"); 

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

String tmp = new String("some property value"); 
SomeObject so1 = new SomeObject(tmp); 
// Not that you would normally write it in this way. 

(बिल्कुल सटीक होना करने के लिए - इन वास्तव में समान नहीं होते हैं मूल में 'नए स्ट्रिंग' संकलन समय पर बनाया है और .class छवि का हिस्सा है।। आप इसे एक प्रदर्शन हैक के रूप में सोच सकते हैं।)

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

अगला JVM एक नए SomeObject के लिए स्थान आवंटित करता है। जावा की आंतरिक बहीखाता और ऑब्जेक्ट के प्रत्येक फ़ील्ड के लिए जगह के लिए यह कुछ जगह है। इस मामले में, केवल एक फ़ील्ड है, strSomeProperty

ध्यान रखें कि strSomeProperty केवल एक स्ट्रिंग का संदर्भ है। अभी के लिए, इसे शून्य करने के लिए शुरू किया जाएगा।

अगला, निर्माता को निष्पादित किया जाता है।

this.strSomeProperty = strSomeProperty; 

यह सब करता है स्ट्रिंग के लिए संदर्भ कॉपी, अपने strSomeProperty क्षेत्र में है।

अंत में, ऑब्जेक्ट संदर्भ so1 के लिए स्थान आवंटित किया गया है। यह SomeObject के संदर्भ के साथ सेट है।

so2 बिल्कुल वैसे ही काम करता है।

+3

नहीं, यह और अधिक जटिल की तुलना में यह लग रहा है नहीं है। "ए" और नया स्ट्रिंग ("ए") बराबर अभिव्यक्ति नहीं है। स्ट्रिंग अक्षरक संकलक द्वारा प्रशिक्षित होते हैं। जब वे उपयोग किए जाते हैं तो वे अतिरिक्त ढेर आवंटन नहीं करते हैं। – bendin

+0

http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5 – bendin

+0

टच :) हालांकि मुझे लगता है कि इंटर्निंग मैंने जो भी लिखा है उससे कहीं अधिक जटिल है। मुझे लगता है कि उचित उत्तर प्रश्न के इरादे पर निर्भर करता है। – slim

6

Determining Memory Usage in Java डॉ हेनज़ एम। क्यूबुट द्वारा एक सटीक उत्तर, साथ ही स्मृति उपयोग की गणना करने के लिए एक कार्यक्रम देता है। प्रासंगिक भाग:

  1. कक्षा कम से कम 8 बाइट लेती है। तो, यदि आप नया ऑब्जेक्ट() कहते हैं; आप ढेर पर 8 बाइट आवंटित करेंगे।
  2. प्रत्येक डेटा सदस्य 4 बाइट्स लेता है, जो लंबे और डबल को छोड़कर 8 बाइट्स लेता है।भले ही डेटा सदस्य बाइट है, फिर भी यह 4 बाइट लेगा! इसके अलावा, 8 बाइट ब्लॉक में इस्तेमाल की गई स्मृति की मात्रा में वृद्धि हुई है। इसलिए, यदि आपके पास एक कक्षा है जिसमें एक बाइट है, तो कक्षा के लिए 8 बाइट और डेटा के लिए 8 बाइट्स ले लेंगे, कुल 16 बाइट्स (ग्रोन!)।
  3. Arrays थोड़ा और चालाक हैं। प्राइमेटिव्स को सरणी में पैक किया जाता है, इसलिए यदि आपके पास बाइट्स की एक सरणी है तो वे प्रत्येक एक बाइट ले लेंगे (वाह!)। पाठ्यक्रम का स्मृति उपयोग अभी भी 8 बाइट ब्लॉक में चला जाता है।

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

+1

ध्यान दें कि यह 7 साल का है, और उस समय एक विशेष ऑपरेटिंग सिस्टम पर एक विशेष जेवीएम का उपयोग करके अनुभवजन्य साक्ष्य के आधार पर (लेख उतना ही कहता है)। जब तक आप यह सुनिश्चित न करें कि आप जिस जेवीएम पर चल रहे हैं, आप यह सटीक नहीं हो सकते हैं। – slim

+0

अच्छा बिंदु। मुझे आश्चर्य नहीं होगा अगर कुछ चीजें जो 4 बाइट्स लेती थीं 64 बिट प्लेटफ़ॉर्म पर 8 लेती हैं। हालांकि, कार्यक्रम अनुभवी वस्तु के आकार को निर्धारित करता है। लक्ष्य वीएम पर इसे चलाने से एक सटीक उत्तर मिलेगा। –

+0

यह अच्छा है। धन्यवाद। – DragonBorn

3

अंक याद करने के लिए:

  1. जब एक विधि कहा जाता है, एक फ्रेम ढेर के शीर्ष पर बनाया जाता है।
  2. एक बार एक विधि निष्पादन पूरा हो जाने के बाद, नियंत्रण का प्रवाह कॉलिंग विधि पर वापस आ जाता है और इसके संबंधित स्टैक फ्रेम को फ्लश किया जाता है।
  3. स्टैक में स्थानीय चर बनाए जाते हैं।
  4. ढेर & में इंस्टेंस वेरिएबल्स बनाए गए हैं, वे ऑब्जेक्ट का हिस्सा हैं।
  5. स्टैक में संदर्भ चर बनाए जाते हैं।

रेफरी: http://www.javatutorialhub.com/java-stack-heap.html

+0

Pls हीप में प्रीमानेंट ग्रेनरेशन के बारे में भी exalain .. – Akash5288

+0

* स्थानीय * संदर्भ चर ढेर में बनाए जाते हैं। संदर्भ * उदाहरण सदस्य * ढेर में, युक्त वस्तु में बनाए जाते हैं। इनमें से कोई भी सवाल का जवाब नहीं देता है। – EJP