रूबी में मेमोरी आवंटन कैसे काम करता है?
रूबी मेमोरी को चंक्स में प्राप्त करता है, जिन्हें पेज कहा जाता है, नए ऑब्जेक्ट्स यहां सहेजे जाते हैं।
फिर…
जब ये पेज भर जाते हैं, तो अधिक मेमोरी की आवश्यकता होती है।
रूबी malloc फंक्शन के साथ ऑपरेटिंग सिस्टम से अधिक मेमोरी का अनुरोध करता है।
यह malloc फंक्शन ऑपरेटिंग सिस्टम का हिस्सा है, लेकिन वैकल्पिक कार्यान्वयन हैं जिनका आप उपयोग कर सकते हैं।
उन कार्यान्वयनों में से एक है गूगल का tcmalloc।
TCmalloc गूगल परफॉरमेंस टूल्स सूट का हिस्सा है।
आप इन टूल्स का उपयोग यह पता लगाने के लिए कर सकते हैं कि रूबी वास्तव में मेमोरी कैसे आवंटित करता है।
और LD_PRELOAD एनवायरनमेंट वेरिएबल (लिनक्स में) के लिए धन्यवाद हम अपने सिस्टम के malloc फंक्शन को tcmalloc से बदल सकते हैं।
इस तरह:
LD_PRELOAD="/usr/lib/libtcmalloc.so" ruby -e "puts 123"
लेकिन यह केवल लाइब्रेरी लोड करता है, यह अभी तक कोई डेटा संग्रह सक्षम नहीं करता।
आइए देखें कि यह कैसे किया जाता है।
प्रोफाइलर सक्षम करना
आप एक अतिरिक्त एनवायरनमेंट वेरिएबल (HEAPPROFILE) के साथ tcmalloc के प्रोफाइलर को सक्षम कर सकते हैं।
LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile ruby -e "puts 123"
यह निम्नलिखित आउटपुट उत्पन्न करेगा:
Starting tracking the heap 123 Dumping heap profile to /tmp/profile.0001.heap (Exiting, 2 MB in use)
यहां आप देखते हैं कि प्रोफाइलर सक्षम हो गया है इसकी पुष्टि।
फिर हम देखते हैं:
- प्रोग्राम का आउटपुट
- फाइलनाम (
profile.0001.heap) - हमारे प्रोग्राम द्वारा उपयोग की गई मेमोरी की मात्रा (
2 MB)
इस फाइल को पढ़ने के लिए आपको tcmalloc के साथ शामिल एक अन्य टूल की आवश्यकता होगी।
pprof --text `which ruby` /tmp/profile.0001.heap | head -10
यह निम्नलिखित आउटपुट उत्पन्न करेगा:
Total: 2.4 MB 1.1 44.7% 44.7% 1.1 44.7% 0x00005570fa4df074 0.7 27.8% 72.5% 0.7 27.8% 0x00005570fa4e0c09 0.4 15.3% 87.8% 0.4 15.3% 0x00005570fa4db460 0.1 5.9% 93.7% 0.1 3.2% 0x00005570fa6349a0 0.0 1.4% 98.3% 0.0 0.3% 0x00005570fa589924 0.0 0.3% 98.6% 0.0 0.3% 0x00005570fa59c4f2 0.0 0.2% 98.8% 0.0 0.2% 0x00005570fa4db48a 0.0 0.2% 99.0% 0.0 0.2% 0x00005570fa4dbaa5 0.0 0.2% 99.1% 0.0 0.2% _dl_new_object
खैर, यह सिर्फ मेमोरी एड्रेस का एक गुच्छा है! आपको फंक्शन नाम देखने के लिए डिबगिंग सिंबल्स के साथ रूबी के एक संस्करण की आवश्यकता होगी।
तब आपको यह आउटपुट मिलेगा:
Using local file ruby. Using local file /tmp/profile.0001.heap. Total: 2.9 MB 1.0 36.2% 36.2% 1.0 36.2% objspace_xmalloc0 0.7 26.1% 62.4% 0.7 26.1% aligned_malloc 0.5 18.8% 81.1% 0.5 18.8% objspace_xcalloc 0.3 9.9% 91.0% 0.3 9.9% stack_chunk_alloc 0.1 3.7% 94.7% 0.1 3.7% objspace_xrealloc 0.1 2.7% 97.4% 0.1 2.7% Init_Method 0.0 1.3% 98.7% 0.0 1.7% onig_new_with_source 0.0 0.4% 99.2% 0.8 26.6% heap_page_allocate 0.0 0.2% 99.4% 0.0 0.2% add_bitset
आप यहां देखते हैं कि MRI के किन फंक्शन्स द्वारा कितनी मेमोरी आवंटित की गई थी।
यह जानना दिलचस्प है कि aligned_malloc रूबी ऑब्जेक्ट्स के लिए नए पेज आवंटित करने के लिए उपयोग किया जाने वाला फंक्शन है, stack_chunk_alloc GC द्वारा मार्किंग चरण के दौरान उपयोग किया जाता है, और objspace_xmalloc0 / objspace_xcalloc स्ट्रिंग्स, सरणियों और किसी भी अन्य डेटा के लिए स्थान आवंटित करते हैं जो RVALUE स्ट्रक्चर में फिट नहीं होते।
अब:
TCmalloc रूबी ऑब्जेक्ट्स के बारे में कुछ नहीं जानता, यह केवल malloc, calloc और realloc के कॉल्स को ट्रैक करता है ताकि यह पता लगा सके कि कितनी मेमोरी का अनुरोध किया गया है।
यदि आप रूबी स्तर पर हीप डंप प्राप्त करना चाहते हैं तो आप ObjectSpace.dump_all का उपयोग कर सकते हैं। यह आपको अपने एप्लिकेशन में सभी लाइव ऑब्जेक्ट्स और उनके मेमोरी आकार के साथ एक JSON फाइल देता है।
लेकिन tcmalloc आपको उन सभी C फंक्शन्स का विज़ुअलाइज़ेशन दिखा सकता है जो मेमोरी का अनुरोध करते हैं।
pprof --web `which ruby` /tmp/profile.0001.heap
यह क्रोम या फायरफॉक्स को एक SVG फाइल के साथ खोलेगा जो ऐसा दिखता है:

न केवल TCmalloc आपको यह अच्छी प्रोफाइलिंग क्षमता देता है, बल्कि इसका उपयोग करके आप अपने एप्लिकेशन के प्रदर्शन को 4-9% तक बढ़ा सकते हैं! आप jemalloc भी आज़मा सकते हैं, जो एक और malloc कार्यान्वयन है जिसमें प्रोफाइलर भी शामिल है।
सारांश
आपने सीखा कि gperftools (गूगल परफॉरमेंस टूल्स) का उपयोग रूबी इंटरप्रेटर के मेमोरी उपयोग को विज़ुअलाइज़ और विश्लेषण करने के लिए कैसे करें।
पढ़ने के लिए धन्यवाद! 🙂