रूबी मेमोरी प्रबंधन
<पी> रूबी वस्तुएं ढेर पर संग्रहीत होती हैं, और प्रत्येक वस्तु ढेर पर एक स्लॉट भरती है। <पी> रूबी 3.1 से पहले, ढेर पर सभी स्लॉट एक ही आकार के थे - सटीक होने के लिए 40 बाइट्स। एक खांचे में फिट होने के लिए बहुत बड़ी वस्तुओं को ढेर के बाहर संग्रहीत किया गया था। प्रत्येक स्लॉट में एक संदर्भ शामिल होता है कि वस्तुओं को कहाँ ले जाया गया था। <पी> रूबी 3.1 में,String के लिए परिवर्तनीय चौड़ाई आवंटन वस्तुओं का विलय कर दिया गया। जल्द ही, परिवर्तनीय चौड़ाई आवंटन एलोबजेक्ट प्रकारों के लिए आदर्श होगा। <पी> परिवर्तनीय चौड़ाई आवंटन का लक्ष्य कैशेलोकैलिटी में सुधार करके प्रदर्शन में सुधार करना है - किसी ऑब्जेक्ट की सभी जानकारी दो मेमोरी स्थानों के बजाय एक ही स्थान पर संग्रहीत की जाएगी। <पी> इसे मेमोरी प्रबंधन के (कुछ हिस्सों) को भी सरल बनाना चाहिए। फिलहाल, दो 'ढेर' हैं: - रूबी हीप (या GC हीप) जो छोटी रूबी वस्तुओं को संग्रहीत करता है।
- सी हीप (या मॉलोक/क्षणिक हीप) जो बड़ी वस्तुओं को संग्रहीत करता है।
- ढेर का प्रारंभिक आकार -
RUBY_GC_HEAP_INIT_SLOTS - जीसी होने के बाद उपलब्ध होने वाले निःशुल्क स्लॉट की संख्या -
RUBY_GC_HEAP_FREE_SLOTS - ढेर का विस्तार -
RUBY_GC_HEAP_GROWTH_FACTORद्वारा किया जाता है
रूबी में कचरा संग्रहण
<पी> रूबी में कचरा संग्रहण 'दुनिया को रोक देता है' - जीसी होने पर कोई अन्य प्रक्रिया नहीं होती है। रूबी में कचरा संग्रहण (2.1 से) भी पीढ़ीगत है , जिसका अर्थ है कि कचरा संग्राहक के दो मोड हैं:- मामूली जीसी - 'युवा' वस्तुओं (हाल ही में बनाई गई वस्तुएं) का निरीक्षण करता है
- मेजर जीसी - 'पुरानी' वस्तुओं के साथ-साथ 'युवा' वस्तुओं (सभी) का निरीक्षण करता है ऑब्जेक्ट्स)
3 जीसी चलता है, बड़ा या छोटा। <पी> जब ढेर भर जाता है, तो सबसे पहले माइनर जीसी को लागू किया जाता है। यदि यह सीमा से नीचे पर्याप्त स्लॉट खाली नहीं कर पाता है, तो प्रमुख जीसी लागू किया जाएगा। केवल तभी, यदि अभी भी पर्याप्त खाली स्लॉट नहीं हैं, तो ढेर का विस्तार किया जाएगा। <पी> मेजर जीसी माइनर जीसी से अधिक महंगी है क्योंकि यह अधिक वस्तुओं को देखती है। <पी> जेनरेशनल जीसी अधिक प्रदर्शनशील क्यों है इसके पीछे सिद्धांत यह है कि वस्तुएं आमतौर पर दो श्रेणियों में आती हैं: - वस्तुएं जो आवंटित की जाती हैं और फिर जल्दी ही दायरे से बाहर हो जाती हैं। रेल्स ऐप में, पेज को रेंडर करने के लिए डीबी से लाए गए मॉडल अनुरोध समाप्त होने पर दायरे से बाहर हो जाएंगे।
- वस्तुएं जो आवंटित की जाती हैं और लंबे समय तक रखी जाती हैं। किसी ऐप के पूरे जीवनकाल में क्लास और कैश अभी भी उपयोग में रहने की संभावना है।
RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR द्वारा नियंत्रित किया जा सकता है। पर्यावरण चर. <पी> जब आपके पास रिसाव होता है, तो आप ऐसी वस्तुएं बनाते हैं जिन्हें साफ नहीं किया जा सकता - अधिक से अधिक old वस्तुएं. इसका मतलब यह है कि प्रमुख (महंगा) GC जितनी बार चलना चाहिए उससे कहीं अधिक बार चलेगा। चूँकि जब GC चल रहा होता है तो कुछ भी नहीं चलता है, यह वह समय है जिसे आप बर्बाद करते हैं। <पी> रूबी में मेमोरीलेआउट और गारबेज कलेक्टर पर आगे पढ़ने के लिए मैंने इस लेख के अंत में कुछ लिंक छोड़े हैं। रूबी में मेमोरी लीक कैसा दिखता है?
<पी> आप किसी भी यूनिक्स सिस्टम पर उपलब्ध सरल टूल का उपयोग करके मेमोरी लीक देख सकते हैं। उदाहरण के तौर पर निम्नलिखित कोड लें। <पी> इस कोड को 'लीक' कहना थोड़ा अनुचित है - यह जो कुछ करता है वह लीक है! —लेकिन यह हमारे उद्देश्यों को पूरा करता है। <पी> हम इस प्रोग्राम को एक टर्मिनल औरwatch में चलाकर कमांड लाइन से रिसाव का काफी सरलता से निरीक्षण कर सकते हैं। -ps के साथ समय के साथ मेमोरी बढ़ती है . <पी> pgrep -f "ruby ./leaky.rb" हमारे लिए प्रक्रिया आईडी ढूंढता है, ताकि हम ps को प्रतिबंधित कर सकें केवल उसी प्रक्रिया के लिए आउटपुट जिसमें हम रुचि रखते हैं। जैसा कि आप अनुमान लगा सकते हैं, यह grep जैसा है प्रक्रियाओं के लिए. <पी> watch टूल हमें किसी दिए गए कमांड के आउटपुट को पोल करने और उसे अपडेट करने की अनुमति देता है, जिससे हमें अपने टर्मिनल के भीतर एक लाइव डैशबोर्ड मिलता है। <पी> आपको इस तरह का आउटपुट मिलेगा, जो हर कुछ सेकंड में अपडेट होता है। <पी> आपको %MEM देखना चाहिए और RSS बढ़ रहा है. वे हैं: %MEM- होस्ट मशीन पर मेमोरी के प्रतिशत के रूप में प्रक्रिया द्वारा उपयोग की जाने वाली मेमोरी की मात्रा।RSS(निवासी सेट आकार) - प्रक्रिया द्वारा उपयोग की जाने वाली रैम की मात्रा बाइट्स में।
कचरा कलेक्टर मॉड्यूल के साथ रूबी लीक का पता लगाएं
<पी> हमGC के साथ रूबी कोड के भीतर भी लीक का पता लगा सकते हैं मॉड्यूल. <पी> GC.stat विधि बहुत सारी उपयोगी जानकारी के साथ एक हैश लौटा देगी। यहां, हमारी रुचि :heap_live_slots में है , जो कि ढेर पर उपयोग में आने वाले स्लॉट की संख्या है। यह :heap_free_slots के विपरीत है .लूप के अंत में, हम एक प्रमुख GC को बाध्य करते हैं और उपयोग किए गए स्लॉट की संख्या प्रिंट करते हैं, अर्थात, GC के बाद बची हुई वस्तुओं की संख्या। <पी> जब हम अपना छोटा सा कार्यक्रम चलाते हैं, तो हम देखते हैं कि इसमें अनंत काल तक वृद्धि होती रहती है। हमारे पास एक रिसाव है! हम GC.stat(:old_objects) का भी उपयोग कर सकते थे समान प्रभाव के लिए. <पी> जबकि GC मॉड्यूल का उपयोग यदि देखने के लिए किया जा सकता है हमारे पास एक रिसाव है और (यदि आप अपने puts के साथ पुनः चतुर हैं कथन) जहां रिसाव हो सकता है, हम उस प्रकार की वस्तुओं को देख सकते हैं जो ObjectSpace के साथ लीक हो सकती हैं। मॉड्यूल. <पी> ObjectSpace.count_objects विधि जीवित वस्तुओं की गिनती के साथ एक हैश लौटाती है। T_STRING उदाहरण के लिए, मेमोरी में लाइव स्ट्रिंग्स की संख्या है। हमारे बल्कि लीक प्रोग्राम के लिए, यह मान प्रत्येक लूप के साथ बढ़ता है, यहां तक कि जीसी के बाद भी। हम देख सकते हैं कि हम स्ट्रिंग ऑब्जेक्ट लीक कर रहे हैं। ऐपसिग्नल के साथ उत्पादन में एप्लिकेशन प्रदर्शन की निगरानी
<पी>ps के साथ खेलते समय और GC खिलौना परियोजनाओं के लिए यह एक समझदारी भरा मार्ग हो सकता है—वे उपयोग करने में मज़ेदार और जानकारीपूर्ण भी हैं! — मैं नहीं करुंगा इन्हें प्रोडक्शन ऐप्स में अपने मेमोरी लीक डिटेक्शन समाधान के रूप में अनुशंसित करें। <पी> यह वह जगह है जहां आप एप्लिकेशन परफॉर्मेंस मॉनिटरिंग (एपीएम) टूल का उपयोग करेंगे। यदि आप एक बहुत बड़ी कंपनी हैं, तो आप इन्हें स्वयं बना सकते हैं। हालाँकि, छोटे परिधानों के लिए, एपीएम को तुरंत चुनना ही एक रास्ता है। आपको मासिक सदस्यता का भुगतान करने की आवश्यकता है, लेकिन वे जो जानकारी प्रदान करते हैं वह इसकी भरपाई कर देती है। <पी> मेमोरी लीक का पता लगाने के लिए, आप समय के साथ सर्वर या प्रोसेस मेमोरी उपयोग (कभी-कभी आरएसएस भी कहा जाता है) ग्राफ़ ढूंढना चाहते हैं। तैनात होने के तुरंत बाद एक स्वस्थ ऐप के ऐपसिग्नल के 'प्रोसेस मेमोरी उपयोग' डैशबोर्ड का एक उदाहरण स्क्रीनशॉट यहां दिया गया है: <पी>
<पी> और यहाँ परिनियोजन के बाद एक अस्वास्थ्यकर ऐप है: <पी>
<पी> ऐपसिग्नल जीसी और हीप स्लॉट जैसे रूबी वीएम आंकड़ों को भी सामने लाएगा, जो आपको मेमोरी लीक के लिए और भी स्पष्ट संकेत दे सकता है। यदि लाइव स्लॉट की संख्या बढ़ती रहती है, तो आपके पास एक रिसाव है! <पी>
<पी> रूबी के लिए ऐपसिग्नल के बारे में और पढ़ें। समाप्ति और आगे की पढ़ाई
<पी> इस पोस्ट में, हमने रूबी के मेमोरी प्रबंधन और कचरा संग्रहकर्ता का एक त्वरित दौरा किया। फिर हमने निदान किया कि यूनिक्स टूल और रूबी के जीसी मॉड्यूल का उपयोग करके मेमोरी लीक का पता कैसे लगाया जाए। <पी> अगली बार, हम देखेंगे किmemory_profiler का उपयोग कैसे करें और derailed_benchmarks लीक ढूंढने और ठीक करने के लिए। <पी> इस बीच, आप हमारे द्वारा उपयोग किए गए टूल के बारे में अधिक पढ़ सकते हैं: watchpspgrep
GCमॉड्यूल दस्तावेज़ीकरणObjectSpaceमॉड्यूल दस्तावेज़ीकरण- कचरा संग्रहण गहन गोता
- परिवर्तनीय चौड़ाई आवंटन