मेमोरी प्रबंधन Java
⚡ स्मार्ट सारांश
मेमोरी प्रबंधन Java यह बताता है कि JVM रनटाइम मेमोरी को स्टैक, हीप और अन्य भागों में कैसे विभाजित करता है। Codeइसमें स्टैटिक क्षेत्र, मेथड कॉल के दौरान ऑब्जेक्ट रेफरेंस का प्रवाह कैसे होता है, और गार्बेज कलेक्टर अप्राप्य ऑब्जेक्ट्स को कैसे पुनः प्राप्त करता है, ताकि एप्लिकेशन स्थिर रहें और मेमोरी लीक से मुक्त रहें, जैसी बातें शामिल हैं।
स्टैक मेमोरी क्या है? Java?
स्टैक मेमोरी में Java स्टैक, JVM मेमोरी का वह क्षेत्र है जो प्रत्येक थ्रेड के लिए मेथड फ्रेम, लोकल वेरिएबल और रेफरेंस वेरिएबल को स्टोर करता है। स्टैक को हमेशा लास्ट-इन-फर्स्ट-आउट क्रम में एक्सेस किया जाता है, इसलिए सबसे हाल ही में कॉल किया गया मेथड सबसे ऊपर होता है, और इसके लोकल वेरिएबल फ्रेम के साथ ही पुश और पॉप किए जाते हैं।
प्रत्येक धागे में Java वर्चुअल मशीन को अपना खुद का स्टैक मिलता है, जो मेथड इनवोकेशन को अलग-थलग और थ्रेड-सेफ बनाए रखता है। int, boolean और double जैसी प्रिमिटिव लोकल वैरिएबल सीधे फ्रेम के अंदर रहती हैं, जबकि स्टैक पर स्टोर किए गए ऑब्जेक्ट रेफरेंस हीप पर एलोकेटेड ऑब्जेक्ट्स को पॉइंट करते हैं।
हीप मेमोरी क्या है? Java?
हीप मेमोरी साझा जेवीएम क्षेत्र है जो प्रत्येक मेमोरी को संग्रहीत करता है। Java new ऑपरेटर का उपयोग करके ऑब्जेक्ट और ऐरे बनाए जाते हैं, साथ ही उन ऑब्जेक्ट से संबंधित सभी संदर्भ चर भी इंस्टेंस फ़ील्ड के रूप में शामिल होते हैं। स्टैक के विपरीत, हीप सभी थ्रेड्स में साझा होता है, यही कारण है कि ऑब्जेक्ट एक्सेस के लिए अक्सर सिंक्रोनाइज़ेशन की आवश्यकता होती है।
हीप वह क्षेत्र है जिसे गार्बेज कलेक्टर प्रबंधित करता है। आधुनिक हॉटस्पॉट जेवीएम हीप को अल्पकालिक वस्तुओं के लिए यंग जेनरेशन और दीर्घकालिक वस्तुओं के लिए ओल्ड जेनरेशन में विभाजित करते हैं, जिसमें क्लास मेटाडेटा एक अलग नेटिव क्षेत्र में संग्रहीत होता है जिसे हीस्पेस कहा जाता है।
मेमोरी आबंटन Java
मेमोरी आबंटन Java यह वह प्रक्रिया है जिसके द्वारा JVM प्रोग्राम निष्पादन के दौरान चरों और कक्षाओं एवं संरचनाओं के उदाहरणों के लिए आभासी स्मृति क्षेत्र आरक्षित करता है। किसी ऑब्जेक्ट की घोषणा के समय स्मृति आवंटित नहीं की जाती; केवल एक संदर्भ बनाया जाता है। वास्तविक ऑब्जेक्ट आवंटन new ऑपरेटर के माध्यम से होता है, इसलिए प्रत्येक ऑब्जेक्ट हीप पर रहता है।
RSI Java मेमोरी आवंटन को निम्नलिखित अनुभागों में विभाजित किया गया है:
- ढेर
- धुआँरा
- Code
- स्थिर
रनटाइम के प्रभावी प्रबंधन के लिए मेमोरी का यह विभाजन आवश्यक है।
- RSI Code इस अनुभाग में आपका संकलित डेटा शामिल है। बाईटकोड.
- RSI धुआँरा सेक्शन स्टोर विधियाँ, स्थानीय चर और संदर्भ चर.
- RSI ढेर अनुभाग में शामिल है वस्तुओं और इसमें इंस्टेंस फ़ील्ड के रूप में रखे गए संदर्भ चर भी शामिल हो सकते हैं।
- RSI स्थिर अनुभाग धारण करता है स्थैतिक डेटा और स्थैतिक विधियाँ सभी इंस्टेंसों में साझा किया गया।
स्थानीय और इंस्टेंस चर के बीच अंतर
जेवीएम में प्रत्येक प्रकार के वेरिएबल कहाँ स्थित होते हैं, यह समझने से स्टैक और हीप के व्यवहार को समझने में मदद मिलती है। उदाहरण चर घोषित किया गया है किसी क्लास के अंदर लेकिन किसी भी मेथड के बाहरऔर यह अपने ऑब्जेक्ट के हिस्से के रूप में हीप पर मौजूद रहता है।
class Student{ int num; // num is instance variable public void showData{}
A स्थानीय चर घोषित किया गया है किसी मेथड के अंदर, मेथड आर्गुमेंट्स सहितऔर यह सक्रिय फ्रेम के अंदर स्टैक पर मौजूद रहता है।
public void sum(int a){ int x = a + 3; // a, x are local variables }
स्टैक और हीप के बीच अंतर
स्टैक और हीप JVM के भीतर अलग-अलग समस्याओं का समाधान करते हैं। स्टैक प्रत्येक थ्रेड को मेथड स्कोप से जुड़े अल्पकालिक डेटा के लिए तेज़, निश्चित आवंटन प्रदान करता है, जबकि हीप दीर्घकालिक ऑब्जेक्ट्स के लिए एक साझा क्षेत्र प्रदान करता है जिसे कोई भी थ्रेड संदर्भित कर सकता है। नीचे दिया गया छोटा वीडियो विस्तृत प्रक्रिया से पहले इन दोनों के बीच अंतर को संक्षेप में बताता है।
क्लिक करें यहाँ उत्पन्न करें यदि वीडियो उपलब्ध न हो
यह देखने के लिए कि स्टैक और हीप कैसे सहयोग करते हैं, एक मुख्य विधि पर विचार करें जो विधि m1 को कॉल करती है।
public void m1{ int x = 20; }
JVM स्टैक में, m1 विधि के लिए एक फ्रेम बनाया जाता है।
नीचे दी गई छवि में दिखाए अनुसार, m1 में मौजूद वेरिएबल x को भी स्टैक पर m1 के फ्रेम में बनाया जाता है।
इसके बाद मेथड m1, मेथड m2 को कॉल करता है। स्टैक में, m1 के फ्रेम के ऊपर m2 के लिए एक नया फ्रेम बनाया जाता है।
स्थानीय चर b और c भी स्टैक पर m2 के फ्रेम के अंदर बनाए जाते हैं।
public void m2(int b){ boolean c; }
इसके बाद, m2 विधि m3 को कॉल करती है। फिर से, स्टैक के शीर्ष पर m3 के लिए एक फ्रेम बनाया जाता है, जैसा कि नीचे दिखाया गया है।
अब मान लीजिए कि मेथड m3, Account क्लास के लिए एक ऑब्जेक्ट बनाता है, जिसमें दो ऑब्जेक्ट हैं। आवृत्ति के चर int p और int q.
class Account { int p; int q; }
यह m3 विधि का कोड है।
public void m3(){ Account ref = new Account(); // more code }
स्टेटमेंट new Account() हीप पर Account का एक ऑब्जेक्ट बनाता है।
m3 के लिए फ्रेम के अंदर स्टैक पर संदर्भ चर ref बनाया जाता है।
असाइनमेंट ऑपरेटर रेफरेंस वेरिएबल को हीप पर मौजूद ऑब्जेक्ट की ओर इंगित करने के लिए बाध्य करता है।
एक बार विधि का निष्पादन पूरा हो जाने पर, नियंत्रण वापस कॉलिंग विधि पर आ जाता है, जो इस मामले में विधि m2 है।
विधि m3 के लिए फ्रेम को स्टैक से हटा दिया जाता है।
चूंकि रेफरेंस वेरिएबल अब हीप पर मौजूद ऑब्जेक्ट को इंगित नहीं करता है, इसलिए वह ऑब्जेक्ट गार्बेज कलेक्शन के लिए योग्य हो जाता है।
जब मेथड m2 का कार्य समाप्त हो जाता है, तो उसे स्टैक से हटा दिया जाता है और उसके सभी वेरिएबल अनुपलब्ध हो जाते हैं। मेथड m1 के साथ भी ऐसा ही होता है, और अंततः नियंत्रण मुख्य मेथड को वापस मिल जाता है।
क्या होगा यदि कोई ऑब्जेक्ट किसी अन्य संदर्भ को अपने इंस्टेंस वेरिएबल के रूप में रखता है?
public static void main(String args[]) { A parent = new A(); // more code } class A { B child = new B(); int e; } class B { int c; int d; }
इस मामले में, संदर्भ चर चाइल्ड, A ऑब्जेक्ट के हिस्से के रूप में हीप पर मौजूद होता है, और बदले में अपने स्वयं के B ऑब्जेक्ट को इंगित करता है, जैसा कि नीचे दिखाया गया है।
कचरा संग्रहण क्या है? Java?
कचरा संग्रहण Java यह वह प्रक्रिया है जिसके द्वारा JVM स्वचालित रूप से मेमोरी प्रबंधन करता है। गार्बेज कलेक्टर उन ऑब्जेक्ट्स को ढूंढता है जो अब किसी भी सक्रिय संदर्भ से पहुंच योग्य नहीं हैं और उनकी मेमोरी को पुनः प्राप्त करता है। डायनामिक मेमोरी आवंटन 'नए' ऑपरेटर के माध्यम से होता है, और मेमोरी तब तक आवंटित रहती है जब तक प्रोग्राम ऑब्जेक्ट का कोई संदर्भ नहीं रखता।
जब कोई संदर्भ शेष नहीं रहता, तो ऑब्जेक्ट को अब आवश्यक नहीं माना जाता है, और उसके द्वारा उपयोग की जाने वाली मेमोरी को पुनः प्राप्त किया जा सकता है। किसी ऑब्जेक्ट को नष्ट करने की कोई स्पष्ट आवश्यकता नहीं है क्योंकि Java यह गार्बेज कलेक्टर के माध्यम से डीएलोकेशन को स्वचालित रूप से संभालता है।
इसके पीछे की तकनीक को इस प्रकार जाना जाता है: कचरा इकठा करनावे प्रोग्राम जो मेमोरी को रिलीज़ करने में विफल रहते हैं, अंततः क्रैश हो जाते हैं जब आवंटित करने के लिए कुछ भी नहीं बचता है। ऐसे प्रोग्रामों को कहा जाता है कि उनमें स्म्रति से रिसाव. कचरा संग्रहण Java यह स्वचालित रूप से चलता है कार्यक्रम की पूरी अवधि के दौरान, जिससे मैन्युअल रूप से आवंटन हटाने का बोझ कम हो जाता है और डेटा लीक होने का खतरा कम हो जाता है।
इसके विपरीत, C में, free() फ़ंक्शन के माध्यम से गतिशील रूप से आवंटित मेमोरी को रिलीज़ करने की ज़िम्मेदारी प्रोग्रामर की होती है। यहीं पर Java मेमोरी मैनेजमेंट एक मजबूत लाभ प्रदान करता है।
आधुनिक हॉटस्पॉट जेवीएम विभिन्न वर्कलोड के लिए ट्यून किए गए कई गार्बेज कलेक्टरों के साथ आते हैं। डिफ़ॉल्ट जी1 गार्बेज कलेक्टर मल्टी-गीगाबाइट हीप्स पर संतुलित थ्रूपुट और पॉज़ टाइम को लक्षित करता है। जेडजीसी और शेनान्डोआ बहुत बड़े हीप्स पर सब-मिलीसेकंड पॉज़ का लक्ष्य रखते हैं, जो उन्हेंtracविलंबता-संवेदनशील सेवाओं के लिए सक्रिय। सही कलेक्टर का चयन करना और यंग जनरेशन, ओल्ड जनरेशन और स्पेस साइज़ को ट्यून करना एक मुख्य कौशल है। Java प्रदर्शन कार्य।
नोट: सभी ऑब्जेक्ट मेमोरी के हीप सेक्शन में बनाए जाते हैं, जो कि वह क्षेत्र है जिसे गार्बेज कलेक्टर प्रबंधित करता है।
उदाहरण: कचरा संग्रह तंत्र सीखने के लिए Java
यह विस्तृत प्रक्रिया दर्शाती है कि एक सरल प्रोग्राम के भीतर संदर्भ कब गार्बेज कलेक्शन के लिए योग्य हो जाते हैं।
चरण 1) निम्नलिखित कोड को संपादक में कॉपी करें।
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
चरण 2) कोड को सेव करें, कंपाइल करें और रन करें। जैसा कि चित्र में दिखाया गया है, दो ऑब्जेक्ट और दो रेफरेंस वेरिएबल बनाए जाते हैं।
चरण 3) लाइन 20, 21 और 22 से कमेंट हटा दें। कोड को सेव करें, कंपाइल करें और रन करें।
चरण 4) नीचे दिए गए चित्र में दिखाए अनुसार, अब दो संदर्भ चर एक ही वस्तु को इंगित करते हैं।
चरण 5) पंक्ति 23 और 24 से टिप्पणी हटाएँ। कोड को सहेजें, संकलित करें और चलाएँ।
चरण 6) जैसा कि नीचे दिखाया गया है, s2 शून्य हो जाता है, लेकिन s3 अभी भी ऑब्जेक्ट को इंगित करता है, इसलिए ऑब्जेक्ट अभी तक गार्बेज कलेक्शन के लिए योग्य नहीं है।
चरण 7) पंक्ति 25 और 26 से टिप्पणी हटाएँ। कोड को सहेजें, संकलित करें और चलाएँ।
चरण 8) इस समय, ऑब्जेक्ट की ओर कोई संदर्भ इंगित नहीं करता है, इसलिए यह गार्बेज कलेक्शन के लिए योग्य हो जाता है। गार्बेज कलेक्टर इसे मेमोरी से हटा देता है, और इसे पुनः प्राप्त करने का कोई तरीका नहीं है।
किसी ऑब्जेक्ट को कैसे डिलीट करें Java?
Java इसमें मैन्युअल डिलीट ऑपरेटर उपलब्ध नहीं है, इसलिए मानक तरीका यह है कि ऑब्जेक्ट के सभी संदर्भों को हटा दिया जाए ताकि गार्बेज कलेक्टर उसे पुनः प्राप्त कर सके।
1) किसी ऑब्जेक्ट को गार्बेज कलेक्शन के लिए योग्य बनाने के लिए, उस ऑब्जेक्ट को इंगित करने वाले प्रत्येक संदर्भ चर को नल असाइन करें।
2) प्रिमिटिव प्रकार ऑब्जेक्ट नहीं होते हैं, इसलिए उन्हें नल मान नहीं दिया जा सकता है। आसपास के स्टैक फ्रेम को पॉप करने पर उनका स्टोरेज स्वचालित रूप से पुनः प्राप्त हो जाता है।



















