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 का लेख Troubleshooting high memory usage with ASP.Net Core on Kubernetes और Fundamentals of Garbage Collection Microsoft द्वारा। दोनों बहुत अच्छे पढ़ने के लिए हैं और Ed-Pro में मेमोरी उपयोग में स्पष्टता लाए।

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

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

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

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

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

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

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

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

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

लेखक: Chuck Conway एक AI इंजीनियर हैं जिनके पास सॉफ्टवेयर इंजीनियरिंग का लगभग 30 साल का अनुभव है। वह व्यावहारिक AI सिस्टम बनाते हैं—कंटेंट पाइपलाइन, इंफ्रास्ट्रक्चर एजेंट, और ऐसे टूल जो वास्तविक समस्याओं को हल करते हैं—और अपनी सीख को साझा करते हैं। सोशल मीडिया पर उनसे जुड़ें: X (@chuckconway) या YouTube और SubStack पर उनसे मिलें।

↑ शीर्ष पर वापस जाएं

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