Skip to content

पोस्ट

.Net Core में गार्बेज कलेक्शन के प्रकार

2 सितंबर 2019 • 5 मिनट पढ़ना

.Net Core में गार्बेज कलेक्शन के प्रकार

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

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

मैं डेवलपमेंट टीम का हिस्सा था।

मेरा पहला पड़ाव टेस्टिंग लॉग्स था, Ed-Pro के लॉग्स ने उच्च मेमोरी उपयोग की ओर इशारा किया, शायद कोई मेमोरी लीक था? एक इंजीनियर ने देखा कि Ed-Pro की गणनाओं में बड़ी मात्रा में अल्पकालिक मेमोरी का उपयोग होता था। यदि मेमोरी को जल्दी साफ नहीं किया गया, तो यह मेमोरी लीक की तरह दिख सकता था।

Ed-Pro .Net Core के ऊपर बनाया गया है, जो Microsoft का मल्टी-प्लेटफॉर्म फ्रेमवर्क है। .Net Core में, मेमोरी को तीन टैग्स में विभाजित किया गया है: अल्पकालिक (Gen0), मध्यम अवधि (Gen1), और दीर्घकालिक (Gen2)। Gen0 अल्पकालिक डेटा के लिए है जो जल्दी स्कोप से बाहर हो जाता है, Gen1 मध्यम अवधि की मेमोरी के लिए है जो थोड़ी देर तक रहती है, यह भी अंततः स्कोप से बाहर हो जाती है और Gen2 दीर्घकालिक मेमोरी है जो एप्लिकेशन के जीवन भर रह सकती है। Gen0 मेमोरी लगातार पुनः प्राप्त की जाती है, Gen1 को Gen0 की तुलना में कम बार पुनः प्राप्त किया जाता है, और Gen2 को Gen1 की तुलना में और भी कम बार पुनः प्राप्त किया जाता है।

Ed-Pro के मेमोरी उपयोग को समझने का एकमात्र निश्चित तरीका इसे प्रोफाइल करना था, नीचे JetBrains के dotMemory का उपयोग करके एक स्क्रीनशॉट है।

जैसा कि संदेह था, हमें बड़ी मात्रा में Gen0 मेमोरी (नीला) मिली, इतनी अधिक कि ऐसा लगता था कि गार्बेज कलेक्शन इसके साथ तालमेल नहीं बिठा सकता। बड़ी मात्रा में मेमोरी की भरपाई के लिए एक रणनीति ने गार्बेज कलेक्शन को मेमोरी स्पेस बढ़ाने (एप्लिकेशन के उपयोग के लिए अधिक मेमोरी जोड़ना) और इसे साफ करने के बीच दोलन करने का कारण बना। सफाई चक्र के दौरान, एप्लिकेशन अनुत्तरदायी हो जाता है।

पहले तो हम हैरान थे, क्या GC का उद्देश्य मेमोरी को साफ रखना नहीं है? दो लेख हमारी समझ में सहायक थे कि .Net में गार्बेज कलेक्शन कैसे काम करता है: Mark Vincze’s का लेख Troubleshooting high memory usage with ASP.Net Core on Kubernetes और Microsoft का Fundamentals of Garbage Collection। दोनों बेहतरीन पढ़ने योग्य हैं और Ed-Pro में मेमोरी उपयोग पर स्पष्टता लाए।

यहाँ हमने जो सीखा उसका सारांश है, .Net में दो प्रकार के गार्बेज कलेक्शन हैं: सर्वर गार्बेज कलेक्शन और वर्कस्टेशन गार्बेज कलेक्शन।

सर्वर गार्बेज कलेक्शन कुछ धारणाएं बनाता है: पहला, पर्याप्त मेमोरी उपलब्ध है और दूसरा, प्रोसेसर मल्टी-कोर हैं और तेज़ हैं। दोनों सच हो सकते हैं, लेकिन हम वर्चुअल मशीनों और Docker की दुनिया में रहते हैं जहाँ यह अधिक संभावना है कि दोनों धारणाएं गलत हैं।

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

वर्कस्टेशन गार्बेज कलेक्शन अलग तरीके से काम करता है। यह लगातार चलता रहता है और एप्लिकेशन के समान प्राथमिकता वाले थ्रेड पर मेमोरी को पुनः प्राप्त करता है। इसका मतलब है कि यह एप्लिकेशन के साथ संसाधनों के लिए प्रतिस्पर्धा भी कर रहा है जो एप्लिकेशन की धीमी गति का कारण बन सकता है। फायदा यह है कि एप्लिकेशन का मेमोरी उपयोग काफी कम रह सकता है, मुख्यतः जब यह बड़ी मात्रा में Gen0 का उपयोग करता है।

डिफ़ॉल्ट के रूप में, यदि .Net Core एक सर्वर का पता लगाता है, तो यह सर्वर गार्बेज कलेक्शन प्रकार चलाता है, जो हमारे एप्लिकेशन के साथ मामला था। वर्कस्टेशन गार्बेज कलेक्शन प्रकार चलाने के लिए अपनी प्रोजेक्ट फ़ाइल में निम्नलिखित स्निपेट जोड़ें:

  <PropertyGroup> 
    <ServerGarbageCollection>false</ServerGarbageCollection>
  </PropertyGroup>

हमने Ed-Pro में यह कॉन्फ़िगरेशन परिवर्तन किया, dotMemory का उपयोग करके, हमने वर्कस्टेशन गार्बेज कलेक्शन सक्षम के साथ Ed-Pro की मेमोरी को प्रोफाइल किया और पिछले परीक्षण की तरह ही स्क्रीन लोड की। यहाँ परिणाम हैं:

मेमोरी उपयोग काफी कम हो गया है। Gen0 आवंटन वस्तुतः अस्तित्वहीन हैं। ग्राफ में अंतर के अलावा, सर्वर गार्बेज कलेक्शन मेमोरी उपयोग 1 गीगा तक पहुंचा जबकि वर्कस्टेशन गार्बेज कलेक्शन लगभग 200 मेगा पर पहुंचा।

हर एप्लिकेशन अलग होता है। हमारे एप्लिकेशन ने बहुत सारे अस्थायी डेटा का उपयोग किया और इस प्रकार बहुत सारी Gen0 मेमोरी का उपयोग करता है। आपका एप्लिकेशन लंबी अवधि की मेमोरी जैसे Gen1 या Gen2 का लाभ उठा सकता है जिसमें सर्वर गार्बेज कलेक्शन बहुत समझदारी की बात है। मेरी सलाह है कि मेमोरी कैसे उपयोग की जाती है इसका अंदाजा लगाने के लिए विभिन्न स्थितियों में अपनी मेमोरी को प्रोफाइल करें और फिर तय करें कि आपके एप्लिकेशन के लिए कौन सा मोड सबसे अच्छा है।

लेखक: चक कॉनवे सॉफ्टवेयर इंजीनियरिंग और जेनेरेटिव AI में विशेषज्ञता रखते हैं। उनसे सोशल मीडिया पर जुड़ें: X (@chuckconway) या उन्हें YouTube पर देखें।

↑ शीर्ष पर वापस

आपको यह भी पसंद आ सकता है