Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

Ruby में मेमोरी ब्लोट को खत्म करें: इष्टतम परफॉरमेंस के लिए सिद्ध रणनीतियाँ

Ruby एप्लिकेशन्स में मेमोरी ब्लोट का मुद्दा अक्सर चर्चा का विषय होता है। इस पोस्ट में, हम देखेंगे कि Ruby मेमोरी मैनेजमेंट कैसे गलत हो सकता है, और आप अपने Ruby एप्लिकेशन को फटने से रोकने के लिए क्या कर सकते हैं।

सबसे पहले, हमें यह समझने की आवश्यकता है कि एप्लिकेशन की मेमोरी के संदर्भ में ब्लोट का क्या अर्थ है।

आइए गोता लगाएं!

Ruby में मेमोरी ब्लोट क्या है?

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

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

इससे पहले कि हम मेमोरी ब्लोट का निदान और समाधान कैसे करें, इसका पता लगाएं, आइए Ruby की मेमोरी आर्किटेक्चर का एक त्वरित पूर्वाभ्यास करें।

Ruby की मेमोरी संरचना

Ruby का मेमोरी उपयोग विशिष्ट तत्वों के इर्द-गिर्द घूमता है जो उपलब्ध सिस्टम संसाधनों के विवेकपूर्ण उपयोग का प्रबंधन करते हैं। इन तत्वों में Ruby भाषा, होस्ट ऑपरेटिंग सिस्टम, और सिस्टम कर्नेल शामिल हैं।

इनके अलावा, गार्बेज कलेक्शन प्रक्रिया भी यह निर्धारित करने में महत्वपूर्ण भूमिका निभाती है कि Ruby मेमोरी कैसे प्रबंधित और पुन: उपयोग की जाती है।

Ruby हीप पेजेस और मेमोरी स्लॉट्स

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

किसी नए ऑब्जेक्ट को मेमोरी आवंटित करते समय, Ruby पहले उपयोग किए गए हीप स्पेस में मुक्त स्लॉट्स की तलाश करता है। यदि कोई नहीं मिलता है, तो यह खाली सेक्शन से एक नया हीप पेज आवंटित करता है।

मेमोरी स्लॉट्स छोटे मेमोरी स्थान हैं, प्रत्येक लगभग 40 बाइट्स आकार का। इन स्लॉट्स से बाहर निकलने वाला डेटा हीप पेज के बाहर एक अलग क्षेत्र में संग्रहीत होता है और प्रत्येक स्लॉट बाहरी जानकारी का एक पॉइंटर संग्रहीत करता है।

एक सिस्टम का मेमोरी एलोकेटर Ruby रनटाइम वातावरण में सभी आवंटन करता है, जिसमें हीप पेजेस और बाहरी डेटा पॉइंटर्स शामिल हैं।

Ruby में ऑपरेटिंग सिस्टम मेमोरी आवंटन

Ruby भाषा द्वारा किए गए मेमोरी आवंटन कॉल्स को होस्ट ऑपरेटिंग सिस्टम के मेमोरी एलोकेटर द्वारा संभाला और प्रतिक्रिया दी जाती है।

आमतौर पर, मेमोरी एलोकेटर में C फंक्शन्स का एक समूह होता है, अर्थात् malloc, calloc, realloc, और free। आइए प्रत्येक पर त्वरित नज़र डालें:

  • Malloc: Malloc का अर्थ मेमोरी आवंटन है, और इसका उपयोग ऑब्जेक्ट्स को मुक्त मेमोरी आवंटित करने के लिए किया जाता है। यह आवंटित की जाने वाली मेमोरी का आकार लेता है और आवंटित मेमोरी ब्लॉक के प्रारंभिक इंडेक्स का एक पॉइंटर लौटाता है।
  • Calloc: Calloc का अर्थ सन्निहित आवंटन है, और यह Ruby भाषा को मेमोरी के सन्निहित ब्लॉक्स आवंटित करने की अनुमति देता है। यह ज्ञात लंबाई के ऑब्जेक्ट एरे आवंटित करते समय फायदेमंद होता है।
  • Realloc: Realloc का अर्थ पुन: आवंटन है, और यह भाषा को नए आकार के साथ मेमोरी को पुन: आवंटित करने की अनुमति देता है।
  • Free: Free का उपयोग पूर्व-आवंटित मेमोरी स्थानों के सेट को साफ़ करने के लिए किया जाता है। यह उस मेमोरी ब्लॉक के प्रारंभिक इंडेक्स का एक पॉइंटर लेता है जिसे मुक्त किया जाना है।

Ruby में गार्बेज कलेक्शन

एक भाषा रनटाइम की गार्बेज कलेक्शन प्रक्रिया नाटकीय रूप से प्रभावित करती है कि यह अपनी उपलब्ध मेमोरी का कितनी अच्छी तरह उपयोग करता है।

Ruby में काफी उन्नत गार्बेज कलेक्शन होता है जो एप्लिकेशन मेमोरी खपत को हर समय अनुकूलित करने के लिए उपरोक्त सभी वर्णित API मेथड्स का उपयोग करता है।

Ruby में गार्बेज कलेक्शन प्रक्रिया के बारे में एक दिलचस्प तथ्य यह है कि यह पूर्ण एप्लिकेशन को रोक देता है! यह सुनिश्चित करता है कि गार्बेज कलेक्शन के दौरान कोई नया ऑब्जेक्ट आवंटन नहीं होता। इस वजह से, आपकी गार्बेज कलेक्शन रूटीन दुर्लभ और जितनी जल्दी हो सके उतनी तेज़ होनी चाहिए।

Ruby में मेमोरी ब्लोट के दो सामान्य कारण

यह सेक्शन Ruby में मेमोरी ब्लोट होने के दो सबसे महत्वपूर्ण कारणों पर चर्चा करेगा: फ्रैगमेंटेशन और स्लो रिलीज़।

मेमोरी फ्रैगमेंटेशन

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

फ्रैगमेंटेशन दो अलग-अलग स्तरों पर हो सकता है: भाषा का स्तर और मेमोरी एलोकेटर का स्तर। आइए इन दोनों को विस्तार से देखें।

Ruby स्तर पर फ्रैगमेंटेशन

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

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

मेमोरी एलोकेटर स्तर पर फ्रैगमेंटेशन

मेमोरी एलोकेटर स्वयं एक समान समस्या का सामना करता है: इसे OS हीप्स को जारी करना होगा जब वे पूरी तरह से मुक्त हों। लेकिन गार्बेज कलेक्शन प्रक्रिया की यादृच्छिक प्रकृति को देखते हुए, एक पूरे OS हीप को एक बार में मुक्त किया जाना असंभव है।

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

स्लो रिलीज़

Ruby में मेमोरी ब्लोट का एक और महत्वपूर्ण कारण मुक्त मेमोरी का सिस्टम पर धीमी गति से वापस जारी होना है। इस स्थिति में, मेमोरी को ऑब्जेक्ट्स को आवंटित किए गए नए मेमोरी ब्लॉक्स की दर से बहुत धीमी गति से मुक्त किया जाता है। हालांकि यह एक पारंपरिक या नौसिखिया मुद्दा नहीं है जिसे हल किया जाए, यह मेमोरी ब्लोट को तीव्रता से प्रभावित करता है — फ्रैगमेंटेशन से भी अधिक!

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

Ruby मेमोरी ब्लोट को कैसे ठीक करें

अब जब हम जानते हैं कि Ruby की मेमोरी को ब्लोट करने का कारण क्या है, तो आइए देखें कि आप इन मुद्दों को कैसे ठीक कर सकते हैं और डीफ्रैगमेंटेशन और ट्रिमिंग के माध्यम से अपने ऐप के परफॉरमेंस में सुधार कर सकते हैं।

डीफ्रैगमेंटेशन के साथ Ruby मेमोरी ब्लोट को ठीक करें

फ्रैगमेंटेशन गार्बेज कलेक्शन के डिज़ाइन के कारण होता है, और इसे ठीक करने के लिए आप बहुत कुछ नहीं कर सकते। हालांकि, कुछ चरण हैं जिनका पालन करके आप फ्रैगमेंटेड मेमोरी डिस्क के साथ समाप्त होने की संभावनाओं को कम कर सकते हैं:

  • यदि आप किसी ऐसे ऑब्जेक्ट का रेफरेंस घोषित करते हैं जो काफी मात्रा में मेमोरी का उपयोग करता है, तो सुनिश्चित करें कि जब उसका काम पूरा हो जाए तो आप उसे मैन्युअली मुक्त कर दें।
  • अपने सभी स्टेटिक ऑब्जेक्ट आवंटन को एक बड़े ब्लॉक में घोषित करने का प्रयास करें। यह आपके सभी स्थायी क्लासेस, ऑब्जेक्ट्स, और अन्य डेटा को एक ही हीप पेजेस पर रखेगा। बाद में, जब आप डायनामिक आवंटन के साथ खेलते हैं, तो आपको स्टेटिक हीप पेजेस के बारे में चिंता नहीं करनी होगी।
  • यदि संभव हो, तो अपने कोड की शुरुआत में बड़े डायनामिक आवंटन करने का प्रयास करें। यह उन्हें आपके बड़े स्टेटिक आवंटन मेमोरी ब्लॉक्स के करीब रखेगा और आपकी बाकी मेमोरी को साफ रखेगा।
  • यदि आप एक छोटे और शायद ही कभी क्लियर होने वाले कैश का उपयोग करते हैं, तो इसे शुरुआत में स्थायी स्टेटिक आवंटन के साथ समूहित करना बेहतर है। आप अपने ऐप के मेमोरी मैनेजमेंट को बेहतर बनाने के लिए इसे पूरी तरह से हटाने पर भी विचार कर सकते हैं।
  • मानक glibc मेमोरी एलोकेटर के बजाय jemalloc का उपयोग करें। यह छोटा सा ट्वीक आपकी Ruby मेमोरी खपत को चार गुना तक कम कर सकता है। यहां एकमात्र चेतावनी यह है कि यह सभी वातावरणों में संगत नहीं हो सकता है, इसलिए प्रोडक्शन में रोल आउट करने से पहले अपने ऐप को अच्छी तरह से टेस्ट करना सुनिश्चित करें।

Ruby मेमोरी ब्लोट को ठीक करने के लिए ट्रिमिंग

स्लो मेमोरी रिलीज़ को ठीक करने के लिए, आपको गार्बेज कलेक्शन प्रक्रिया को ओवरराइड करना होगा और मेमोरी को अधिक बार जारी करना होगा। एक API है जो ऐसा कर सकता है जिसे malloc_trim कहा जाता है। आपको बस इतना करना है कि Ruby को गार्बेज कलेक्शन प्रक्रिया के दौरान इस फंक्शन को कॉल करने के लिए संशोधित करें।

यहां संशोधित Ruby 2.6 कोड है जो gc.c फंक्शन gc_start में malloc_trim को कॉल करता है:

gc_prof_timer_start(objspace); { gc_marks(objspace, do_full_mark); // BEGIN MODIFICATION if (do_full_mark) { malloc_trim(0); } // END MODIFICATION } gc_prof_timer_stop(objspace);

नोट: यह प्रोडक्शन एप्लिकेशन्स में अनुशंसित नहीं है क्योंकि यह आपके ऐप को अस्थिर बना सकता है। हालांकि, यह तब काम आता है जब स्लो मेमोरी रिलीज़ आपके परफॉरमेंस को बड़ा झटका देती है, और आप किसी भी समाधान को आजमाने के लिए तैयार हैं।

समापन और अगले कदम

मेमोरी ब्लोट्स की पहचान करना मुश्किल है और उन्हें ठीक करना और भी चुनौतीपूर्ण है।

इस लेख में Ruby ऐप्स में मेमोरी ब्लोट्स के पीछे दो महत्वपूर्ण कारणों — फ्रैगमेंटेशन और स्लो रिलीज़ — और दो फिक्स: डीफ्रैगमेंटेशन और ट्रिमिंग को देखा गया।

आपको अपने ऐप के मेट्रिक्स पर लगातार नज़र रखनी चाहिए ताकि आसन्न ब्लोट घटना की पहचान की जा सके और इससे पहले कि यह आपके ऐप को डाउन कर दे, इसे ठीक किया जा सके।

मुझे उम्मीद है कि मैंने आपके Ruby एप्लिकेशन में मेमोरी ब्लोट को ठीक करने की दिशा में कुछ कदम उठाने में आपकी मदद की है।

P.S. यदि आप Ruby Magic पोस्ट्स को प्रेस से निकलते ही पढ़ना चाहते हैं, तो हमारे Ruby Magic न्यूज़लेटर को सब्सक्राइब करें और कभी भी एक भी पोस्ट मिस न करें!

हमारे गेस्ट ऑथर कुमार हर्ष शिल्प द्वारा एक उभरते सॉफ्टवेयर डेवलपर हैं। वह एक उत्साही लेखक हैं जो Ruby और JavaScript जैसी लोकप्रिय वेब तकनीकों के आसपास कंटेंट तैयार करते हैं। आप उनकी वेबसाइट के माध्यम से उनके बारे में अधिक जान सकते हैं और ट्विटर पर उन्हें फॉलो कर सकते हैं।


  1. रूबी मैट्रिक्स को समझना: परिभाषा, अनुप्रयोग और उन्हें कैसे बनाएं रूबी मैट्रिक्स को समझना: परिभाषा, अनुप्रयोग और उन्हें कैसे बनाएं

    मैट्रिक्स एक 2D (2-डायमेंशनल) ऐरे है जिसका उपयोग स्प्रेडशीट जैसे डेटा को स्टोर और काम करने के लिए किया जा सकता है। इनका उपयोग किया जा सकता है: टेबल गेम में बोर्ड को दर्शाना (शतरंज, चेकर्स, आदि) आंकड़े और डेटा विश्लेषण प्लॉट्स और ग्राफ़ उत्पन्न करना क्योंकि यह एक शक्तिशाली डेटा संरचना है इसलिए इसका

  1. रूबी स्ट्रक्ट्स और OpenStruct में महारत: कुशल वैल्यू ऑब्जेक्ट्स रूबी स्ट्रक्ट्स और OpenStruct में महारत: कुशल वैल्यू ऑब्जेक्ट्स

    रूबी में स्ट्रक्ट क्या है? एक स्ट्रक्ट एक बिल्ट-इन रूबी क्लास है, इसका उपयोग वैल्यू ऑब्जेक्ट्स उत्पन्न करने वाली नई क्लासेस बनाने के लिए किया जाता है। एक वैल्यू ऑब्जेक्ट संबंधित विशेषताओं को एक साथ संग्रहीत करने के लिए उपयोग किया जाता है। यहां एक उदाहरण है: दो निर्देशांकों (x और y) के साथ एक Point।

  1. विंडोज 10 पर क्रोम मेमोरी उपयोग कम करें: त्वरित और प्रभावी टिप्स विंडोज 10 पर क्रोम मेमोरी उपयोग कम करें: त्वरित और प्रभावी टिप्स

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