जब मैं कोई ऑब्जेक्ट बनाता हूं, तो ताजा मेमोरी को इंस्टेंस फील्ड और मेथड या केवल इंस्टेंस फील्ड दोनों के लिए आवंटित किया जाता है


14

मेरी एक निम्न कक्षा है

class Student{

int rollNumber;
int marks;

public void setResult(int rollNumber, int marks){

    this.rollNumber=rollNumber;
    this.marks=marks;   
}

public void displayResult(){

    System.out.println("Roll Number= "+this.rollNumber+"   Marks= "+this.marks);

}
}

अब मैं निम्न प्रकार के छात्र के दो ऑब्जेक्ट बनाता हूं

Student s1=new Student();
Student s2=new Student();

अब मेमोरी के दो अलग-अलग सेट उदाहरण क्षेत्रों के लिए आवंटित किए गए हैं। अब मेरे सवाल है स्मृति विधियों (के लिए आवंटित किया गया है या setResultऔर displayResult) दो बार या एक बार?

कृपया निम्नलिखित आंकड़ा देखें और क्या आप मुझे यह कहने में मदद कर सकते हैं कि कौन सी आकृति सही जानकारी देती है।

यहाँ छवि विवरण दर्ज करें


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

3
मैं सीख रहा हूँ जावा ... और सभी सामग्रियों में वे कहते हैं कि जब भी हम एक वस्तु बनाते हैं तो एक ताज़ा मेमोरी सभी इंस्टेंस फ़ील्ड्स को आवंटित की जाती है..लेकिन, किसी भी सामग्री ने यह नहीं कहा कि ताजा मेमोरी विधियों के लिए आवंटित की जाएगी या नहीं नहीं
हरीश_९

जवाबों:


13

विधियों के लिए कोड Class(अधिक संक्षिप्त रूप से Class<Student>) का हिस्सा है , और कक्षा पहली बार लोड होने पर इसे मेमोरी में लोड किया जाता है।

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

आपके प्रश्न के अनुसार, अब यह स्पष्ट होना चाहिए कि आंकड़ा B सही है (हालांकि यह प्रतिबिंबित नहीं करता है कि जब आप वास्तव में विधि कहते हैं तो क्या होता है)।


ठीक है। अब मैं 90% स्पष्ट हूं .... लेकिन एक छोटी सी शंका .. मान लीजिए अगर मैं 10 प्रकार की छात्र बनाता हूं तो कक्षा 1 में ताजा स्मृति का केवल एक सेट आवंटित किया जाता है, जबकि ताजा स्मृति का 10 सेट है 10 वस्तुओं के लिए स्टोरेज वेरिएबल्स को आवंटित करने के लिए..मैं सही हूं?
हरीश। १_N

सही। यह सोचें कि यह केवल स्मृति को लेने वाले गुण नहीं हैं, उदाहरण के लिए स्वयं से संबंधित एक छोटा सा उपरि है (बिना गुणों वाले वर्ग का उदाहरण 0 बाइट से अधिक का उपयोग करेगा)।
SJuan76

एक और बात ... मैंने जावा को ध्यान में रखते हुए प्रश्न पूछा .... क्या यही बात जावा में होती है .....
हरीश_

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

6

इंस्टेंस फील्ड्स (प्रॉपर्टी बैकिंग फील्ड्स सहित) एन-ऑब्जेक्ट्स के लिए एन-कॉपी प्राप्त करते हैं।

स्टेटिक फील्ड्स को प्रति क्लास एक ही कॉपी मिलती है।

तरीके बाइटकोड (या जेआईटी के बाद, देशी निर्देशों के ब्लॉक) के ब्लॉक हैं जो प्रोग्राम "छवि" या निष्पादन कोड खंड का हिस्सा हैं। विधियाँ पहले से ही प्रोग्राम इमेज का हिस्सा हैं क्योंकि यह डिस्क पर बैठती है। एक बार जब छवि ओएस (या सीएलआर) द्वारा लोड हो जाती है, तो विधि कोड की एकल साझा प्रतिलिपि होती है।

वे सामान्य रूप से "हीप" या रनटाइम आवंटन का हिस्सा नहीं होते हैं, केवल उन मामलों को छोड़कर जहां आप मक्खी पर नए तरीकों को संकलित करने के लिए होस्टेबल कंपाइलर का उपयोग कर सकते हैं। तरीकों को वस्तुओं की तरह "आवंटित" नहीं मिलता है और वे ऑब्जेक्ट निर्माण के सापेक्ष "आवंटित" नहीं होते हैं। वे केवल कार्यक्रम के हिस्से के रूप में मौजूद हैं, इससे पहले कि कोई भी वस्तु कभी तात्कालिक हो। यहां तक ​​कि लैम्ब्डा / डेलीगेट्स को भी मक्खी पर आवंटित नहीं किया जाता है। कंपाइलर इन अन्य प्रतीत होता है गतिशील कोड ऑब्जेक्ट्स को लागू करने के लिए कक्षाएं ऑन-डिमांड बनाता है, और वे डिस्क पर बाइटकोड छवि के हिस्से के रूप में भी मौजूद हैं।

टिप्पणी प्रति अपडेट:

JVM मानक को यह कहना है:

2.5.4। विधि क्षेत्र

जावा वर्चुअल मशीन में एक विधि क्षेत्र है जो सभी जावा वर्चुअल मशीन थ्रेड्स के बीच साझा किया गया है। विधि क्षेत्र एक पारंपरिक भाषा के संकलित कोड के लिए भंडारण क्षेत्र के अनुरूप है या एक ऑपरेटिंग सिस्टम प्रक्रिया में "पाठ" खंड के अनुरूप है। यह प्रति-वर्ग संरचनाओं जैसे रन-टाइम निरंतर पूल, फ़ील्ड और विधि डेटा, और क्लास और उदाहरण इनिशियलाइज़ेशन और इंटरफ़ेस इनिशियलाइज़ेशन में उपयोग किए जाने वाले विशेष तरीकों (.92.9) सहित विधियों और निर्माणकर्ताओं के लिए कोड संग्रहीत करता है।

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

अतः यह स्पष्ट है कि (1) हाँ युक्ति यह निर्धारित नहीं करती है कि यह कैसे किया जाता है, लेकिन (2) यह एक पारंपरिक भाषा के संकलित कोड के लिए भंडारण क्षेत्र के अनुरूप है, अर्थात। पाठ खंड। यह बात मैं बना रहा हूं।


आप जो कह रहे हैं वह समझ में आता है, लेकिन क्या वास्तव में जेएलएस द्वारा इसकी गारंटी दी गई है? आम तौर पर, जेएलएस कार्यान्वयनकर्ताओं को इस तरह के प्रश्नों में बहुत अधिक छूट देता है।
जोर्ग डब्ल्यू मित्तग

उस बिंदु पर निश्चित नहीं, @ JörgWMittag। आप शायद सही हो सकते हैं। मैंने जिस बिंदु को बनाने की कोशिश की, वह "नया टी ()" है, जो किसी विधि का नया उदाहरण आवंटित नहीं करता है। जेवीएम की बारीकियों के अनुसार, क्लास लोडर वास्तव में बाइटकोड को ढेर में संग्रहीत करते हैं, और मुझे लगता है कि ऐसे संभावित परिदृश्य हैं जहां कक्षाएं स्वयं त्वरित और यहां तक ​​कि कचरा एकत्र की जाती हैं। लेकिन यह रनटाइम का कार्यान्वयन विवरण है, और वैचारिक रूप से, मैं जिस ढेर के बारे में बात कर रहा हूं वह "उपयोगकर्ता" ढेर है। सामान्य उपयोगकर्ता के संदर्भ में वर्ग और विधियों को डेटा नहीं माना जाता है। लेकिन जब से हम यूजरलैंड से एक क्लास लोडर को भी नियंत्रित कर सकते हैं, मुझे लगता है कि मुझे नहीं पता है।
कोडेनहेम

JLS भी एक ढेर के बारे में बात नहीं करता है, है ना? यह जावा को डायनामिक स्टैक के साथ लागू करने के लिए पूरी तरह से कानूनी है और परिमित निश्चित आकार के स्टैक और डायनेमिक ढेर के बजाय कोई ढेर नहीं है। JLS JVM के बारे में कुछ भी नहीं कहता है, यह JVM के बिना जावा को लागू करने के लिए पूरी तरह से वैध है।
जॉर्ग डब्ल्यू मित्तग

आप जेएलएस का संदर्भ दे रहे हैं, लेकिन मैं जेवीएम की बात कर रहा हूं। JVM मानक निश्चित रूप से ढेर पर चर्चा करता है। आपको एक वैरिएबल स्कोप / जीवनकाल प्रदान करना चाहिए जो स्टैक के स्थानीय दायरे से बच जाता है। जैसा कि सैद्धांतिक रूप से संभव है, मैं "ज्ञात कार्यान्वयन" के संदर्भ में सोचना पसंद करता हूं। मुझे पूरा यकीन है कि ढेर के बिना एक पूर्ण JVM लागू करना आदिम एक कठिन, या असंभव भी है, क्योंकि JVM एक शुद्ध स्टैक मशीन नहीं है। फोर्थ मशीनों, और अन्य शुद्ध स्टैक आर्किटेक्चर के बारे में मेरी समझ यह है कि यह संभव हो सकता है यदि रैंडम वैरिएबल एक्सेस के लिए एक आदिम मौजूद है, लेकिन मैंने अभी इसे नहीं देखा है।
कोडेनहेम

@ JörgWMittag - मैंने उस उत्तर के साथ कुछ जोड़ा जो हमारी चर्चा के लिए रुचि का हो सकता है। मुद्दा यह है कि मैं पारंपरिक रनटाइम सिस्टम में पारंपरिक कोड या टेक्स्ट सेगमेंट के लिए एक सादृश्य बना रहा था।
कोडेनहेम

-4

ऑब्जेक्ट को हीप मेमोरी में आवंटित किया जाता है। जब ऑब्जेक्ट को नष्ट कर दिया जाता है तो सभी ऑब्जेक्ट के लिए स्लॉट आवंटित किया जाता है और जब ऑब्जेक्ट नष्ट हो जाता है तो नष्ट हो जाता है। उदाहरण के चर को भी ढेर मेमोरी में आवंटित किया जाता है। और स्थानीय वेरिएबल को उस समय स्टैक में बनाया जाता है जब विधि कहा जाता है।


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