यदि आप सोच रहे हैं कि आपके रूबी एप्लिकेशन के साथ क्या हो रहा है…
कोई फैंसी GUI टूल्स नहीं हैं…
लेकिन हमारे पास ObjectSpace मॉड्यूल है!
ObjectSpace आपको अपने एप्लिकेशन की वर्तमान स्थिति के बारे में जानकारी देता है।
आइए खोजें कि यह कैसे काम करता है।
ऑब्जेक्ट्स की गिनती
ObjectSpace का उपयोग करके आप जान सकते हैं कि आपके प्रोग्राम में वर्तमान में कौन से ऑब्जेक्ट्स 'जीवित' हैं।
किसी ऑब्जेक्ट के जीवित होने का क्या मतलब है?
एक ऑब्जेक्ट तब तक जीवित रहता है जब तक उस पर कोई रेफरेंस पॉइंट कर रहा हो। एक रेफरेंस केवल ऑब्जेक्ट तक पहुंचने का एक तरीका है, जैसे एक वेरिएबल या एक कॉन्स्टेंट।
यदि किसी ऑब्जेक्ट तक पहुंचा नहीं जा सकता तो इसका मतलब है कि इसे मेमोरी से हटाना सुरक्षित है।
उदाहरण:
# वेरिएबल 'name' स्ट्रिंग 'Dave' का रेफरेंस रखता है। name = 'Dave' # 'name' वेरिएबल अब 'John' को इंगित करता है। # 'Dave' के पास अब कोई रेफरेंस नहीं है जो उसकी ओर इशारा करता हो। name = 'John'
अब आइए ObjectSpace के एक्शन में एक उदाहरण देखें:
require 'objspace' # यह वैध रूबी सिंटैक्स है, लेकिन irb/pry पर काम नहीं करता ObjectSpace .each_object .inject(Hash.new 0) { |h,o| h[o.class] += 1; h } .sort_by { |k,v| -v } .take(10) .each { |klass, count| puts "#{count.to_s.ljust(10)} #{klass}" } # कॉपी और पेस्ट वर्जन (irb/pry के लिए इसका उपयोग करें) ObjectSpace.each_object.inject(Hash.new 0) { |h,o| h[o.class] += 1; h }.sort_by { |k,v| -v }.take(10).each { |klass, count| puts "#{count.to_s.ljust(10)} #{klass}" } यह आपके टॉप-10 क्लासेस के लिए ऑब्जेक्ट काउंट के साथ एक टेबल प्रिंट करेगा।
Count Class ------------------------- 5436 String 315 Class 251 Array 101 Encoding 69 Regexp 45 Hash 26 Module 25 Gem::Version 22 Gem::StubSpecification::StubLine 22 Gem::StubSpecification
यदि आपको मेमोरी लीक का संदेह है तो आप हर घंटे इस डेटा को लॉग कर सकते हैं और पता लगा सकते हैं कि क्या कोई ऑब्जेक्ट काउंट है जो हर समय बढ़ता रहता है लेकिन कभी कम नहीं होता।
ऑब्जेक्ट्स के साथ मज़ा
ObjectSpace का उपयोग करते समय आपको वास्तविक ऑब्जेक्ट्स तक पहुंच मिलती है, न कि केवल उनके बारे में जानकारी, इसलिए आप कुछ मज़ेदार चीजें कर सकते हैं जैसे सभी स्ट्रिंग्स का मान प्रिंट करना या अपने सभी File ऑब्जेक्ट्स का पथ प्रिंट करना।
उदाहरण:
ObjectSpace .each_object(String) .sort_by { |s| s.size } .each { |s| p s } यह मेमोरी में सभी स्ट्रिंग्स को आकार के अनुसार क्रमबद्ध करके प्रिंट करेगा। आप देखेंगे कि कई स्ट्रिंग्स हैं जिन्हें आपने स्वयं नहीं बनाया, वे रूबी इंटरप्रेटर द्वारा बनाई गई हैं।
व्यावहारिक उपयोग?
खैर, यह ज्यादातर डिबगिंग और आपके ऐप के बारे में आँकड़े इकट्ठा करने के लिए है 🙂
ऑब्जेक्ट मेमोरी साइज़
एक और चीज जो आप कर सकते हैं वह है किसी विशेष ऑब्जेक्ट का मेमोरी साइज़ खोजने के लिए ObjectSpace.memsize_of का उपयोग करना।
उदाहरण:
o = "a" * 100 ObjectSpace.memsize_of(o)
एक बात ध्यान रखने योग्य है यह डॉक्यूमेंटेशन से चेतावनी:
"ध्यान दें कि रिटर्न साइज़ अधूरा है। आपको इस जानकारी को केवल एक संकेत के रूप में मानना चाहिए।"
यदि आप इस मेथड को विभिन्न प्रकार के ऑब्जेक्ट्स के साथ आज़माते हैं तो आपको कुछ दिलचस्प चीजें मिलेंगी, जैसे Fixnum हमेशा 0 लौटाते हैं।
ObjectSpace.memsize_of(42) # 0
इसका कारण यह है कि रूबी आंतरिक रूप से Fixnum ऑब्जेक्ट्स नहीं बनाता है, आप इसके बारे में रूबी में नंबर्स पर लिखी मेरी पोस्ट में अधिक जान सकते हैं।
एक और दिलचस्प स्ट्रिंग्स हैं:
ObjectSpace.memsize_of("A" * 22) # 40 ObjectSpace.memsize_of("A" * 23) # 40 ObjectSpace.memsize_of("A" * 24) # 65 मैं
"A" * sizeका उपयोग लंबी स्ट्रिंग बनाने के तरीके के रूप में करता हूं बिना इसे टाइप किए 🙂
रुको! अभी क्या हुआ?
खैर, पता चला कि रूबी में 24 वर्णों से छोटी स्ट्रिंग्स के लिए एक अंतर्निहित ऑप्टिमाइज़ेशन है, इसलिए उसके बाद मेमोरी उपयोग में उछाल आता है। आप इसे पैट शॉनेसी की इस पोस्ट में अधिक विस्तार से देख सकते हैं।
एलियास्ड मेथड्स कैसे खोजें
क्या यह अच्छा नहीं होगा यदि रूबी में सभी एलियास्ड मेथड्स की एक 'मास्टर' सूची होती?
इच्छा पूरी हुई!
इसे देखें:
class Module def aliased_methods instance_methods(false) .group_by { |m| instance_method(m) } .map(&:last) .keep_if { |symbols| symbols.length > 1 } end end मुझे यह कोड स्टैकओवरफ्लो के एक उत्तर से मिला। यह Module क्लास पर एक aliased_methods मेथड परिभाषित करता है, जो instance_methods मेथड का उपयोग करके एक क्लास पर परिभाषित सभी इंस्टेंस मेथड्स की सूची प्राप्त करता है।
मुझे पता है कि यह थोड़ा भ्रमित करने वाला लग सकता है, लेकिन यह मेटाप्रोग्रामिंग है!
यहां बाकी कोड है, जो उन सभी क्लास नामों की एक सरणी बनाता है जिनके पास कम से कम एक 'जीवित' ऑब्जेक्ट है, फिर यह हर क्लास पर aliased_methods को कॉल करता है और आउटपुट प्रिंट करता है।
objects = ObjectSpace.each_object.map(&:class).uniq objects.each do |klass| methods = "n#{klass}n#{'-'*20}n" klass.send(:aliased_methods).each do |m1, m2| methods << "#{m1.to_s.ljust(15)} #{m2}n" end puts methods end आउटपुट ऐसा दिखता है:
Array -------------------- inspect to_s [] slice length size find_index index collect map collect! map!
निष्कर्ष
मुझे आशा है कि आपको ObjectSpace के साथ की जा सकने वाली अच्छी चीजों के बारे में सीखने में मज़ा आया, अब इसे आज़माएं और मुझे बताएं कि क्या आपको कुछ दिलचस्प मिलता है!
इस पोस्ट को अपने सभी प्रोग्रामर दोस्तों के साथ शेयर करना न भूलें, इससे उन्हें कुछ नया सीखने में मदद मिलेगी और मुझे अधिक पाठक मिलेंगे 🙂