2011-05-11 12 views
5

हेलो, मैं हैश में कुंजी हटाने के बाद स्मृति को कैसे रिलीज़ करने में सफल नहीं हो सकता। जब मैं हैश से कुंजी हटाता हूं, तो स्मृति जारी नहीं होती है और न ही GC.start को मैन्युअल रूप से कॉल करने के बाद। क्या यह अपेक्षित व्यवहार है या हैश से कुंजी हटाए जाने पर जीसी स्मृति जारी नहीं करता है और ये वस्तुएं कहीं लीक हो रही हैं? मैं रूबी में हैश में कुंजी कैसे हटा सकता हूं और इसे स्मृति में भी आवंटित कर सकता हूं?कुंजी हटाने के बाद रूबी हैश मेमोरी लीक

उदाहरण:

irb(main):001:0> `ps -o rss= -p #{Process.pid}`.to_i 
=> 4748 
irb(main):002:0> a = {} 
=> {} 
irb(main):003:0> 1000000.times{|i| a[i] = "test #{i}"} 
=> 1000000 
irb(main):004:0> `ps -o rss= -p #{Process.pid}`.to_i 
=> 140340 
irb(main):005:0> 1000000.times{|i| a.delete(i)} 
=> 1000000 
irb(main):006:0> `ps -o rss= -p #{Process.pid}`.to_i 
=> 140364 
irb(main):007:0> GC.start 
=> nil 
irb(main):008:0> `ps -o rss= -p #{Process.pid}`.to_i 
=> 127076 

पुनश्च: मैं रूबी 1.8.7 का उपयोग करें। मैंने भी 1.9.2 रूबी की कोशिश की है, लेकिन यह बेहतर नहीं था।

+2

मुझे नहीं पता, लेकिन मुझे लगता है कि रूबी उस स्मृति को पुन: उपयोग करने के लिए पूल कर रही है, यह चीजों को करने का एक सुंदर मानक तरीका है। – falstro

+0

अगर कोई एडम के कोड को डुप्लिकेट कर सकता है, लेकिन दिखाता है कि ऑब्जेक्ट्स के सृजन को हटाने और हटाने से कई बार स्मृति उपयोग में वृद्धि नहीं होती है, जो सवाल का जवाब देने में मदद करेगा। –

+0

मेमोरी मुक्त: 1000000.times {| i | एक || = []; एक [i.to_s] = i; @ A.delete (i); GC.start; पी ऑब्जेक्टस्पेस.count_objects} –

उत्तर

1

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

यह एक अपेक्षाकृत सरल स्पष्टीकरण है, लेकिन मूल रूप से, जो आप देख रहे हैं वह सामान्य है।

6

Stackoverflow: How Malloc and Free Work

देखें अच्छे कारणों (ऊपर प्रशस्ति पत्र में लिखा हुआ) वास्तव में कोई स्मृति प्रबंधक विज्ञप्ति वापस ऑपरेटिंग सिस्टम के लिए स्मृति की एक किस्म के लिए।

आपके लिए प्रक्रिया में परिवर्तन देखने के लिए, रूबी दुभाषिया के सी भाग में अंतर्निहित malloc और free को मेजबान ओएस को स्मृति को वापस करने की आवश्यकता होगी। ऐसा होने वाला नहीं है, लेकिन रूबी स्तर पर, वस्तुओं को जीसीड किया गया है और दुभाषिया में स्थानीय रूप से नि: शुल्क सूची में हैं।

2

एक वरिष्ठ डेवलपर हैं जो भाषाओं का एक बहुत में इस चीज के लिए एक लंबे समय कर रहा है के रूप में, यहाँ मेरे विचार है:

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

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

जहां तक ​​यह माना जाता है कि यह एक स्मृति रिसाव है, ठीक है, मुझे लगता है कि यह थोड़ा सा मूर्ख या अजीब है। आपके जैसा एक स्मृति रिसाव उल्लेखनीय रिसाव होगा, और, जैसा कि रूबी आधारित ऐप्स और साइट्स के साथ हैं, किसी ने इसे बहुत समय पहले देखा होगा। इसलिए, जब मैं कुछ ऐसा समझता हूं जो मुझे समझ में नहीं आता है, तो मुझे हमेशा लगता है कि मैं अपने कोड में कुछ गलत कर रहा हूं, तो मैं कुछ काम करता हूं, और यदि मैं वे अभी भी ध्वनि लगते हैं, मैं उन अन्य लोगों की तलाश करूंगा जिनके पास समान समस्याएं हैं और देखें कि उनके पास समाधान हैं या नहीं। और, यदि समस्या ऐसी चीज है जो भाषा के लिए महत्वपूर्ण होगी, तो मैं स्रोत में खोदूँगा या कुछ मूल डेवलपर्स से बात करूंगा और पूछूंगा कि मैं जो देख रहा हूं उसके साथ पागल हूं। मुझे पहले निम्न स्तर की बग मिली है लेकिन वे कोने के मामले हैं, और मैंने कुछ भी उल्लेख करने से पहले चार दिनों में खुदाई की, क्योंकि मैं एक ऐसे साथी की तरह नहीं बनना चाहता था जो एक बग रिपोर्ट दर्ज करे एप्पल के साथ तुरंत, फिर पता लगाएं कि यह उसके कोड में एक बग था।

एक डेलोकेशन पर सिस्टम को वापस लौटने के बारे में मेरी समग्र सोच, क्या यह अतिरिक्त ओवरहेड को घुमाता है जिसे अगले ऑपरेशन में सीपीयू चक्रों को बर्बाद कर दिया जा सकता है, जिसका अर्थ है और व्याख्यान भाषाएं बर्दाश्त नहीं कर सकती हैं क्योंकि वे तेज़ नहीं हैं संकलित भाषाओं के साथ शुरू करने के लिए। मुझे लगता है कि भाषा के लिए यह एक उचित बात है कि इसे बार-बार स्मृति के बड़े ब्लॉक को आवंटित करने की आवश्यकता होगी यदि इसे एक बार करना है, खासकर रुबी जैसे ओओ भाषा के साथ। उस बिंदु पर यह पहले इस्तेमाल की गई स्मृति को पकड़ने के लिए बहुत समझ में आता है।

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

0

यदि आप आवंटन दो बार चलाते हैं तो @digitalross अधिक या कम देखा जा सकता है। अगर वास्तव में ऐसी स्मृति रिसाव थी, तो आप स्मृति आकार को दोगुनी होने की उम्मीद करेंगे, हालांकि ऐसा नहीं होता है।

[~]$ irb           rvm:[email protected] 
1.9.3p0 :001 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 8148 
1.9.3p0 :002 > a = {} 
=> {} 
1.9.3p0 :003 > 1000000.times{|i| a[i] = "test #{i}"} 
=> 1000000 
1.9.3p0 :004 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 101188 
1.9.3p0 :005 > 1000000.times{|i| a.delete(i)} 
=> 1000000 
1.9.3p0 :006 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 90960 
1.9.3p0 :007 > GC.start 
=> nil 
1.9.3p0 :008 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 93388 
1.9.3p0 :009 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 93388 
1.9.3p0 :010 > 1000000.times{|i| a[i] = "test #{i}"} 
=> 1000000 
1.9.3p0 :011 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 140088 
1.9.3p0 :012 > 1000000.times{|i| a.delete(i)} 
=> 1000000 
1.9.3p0 :013 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 130880 
1.9.3p0 :014 > GC.start 
=> nil 
1.9.3p0 :015 > `ps -o rss= -p #{Process.pid}`.to_i 
=> 104256 

पहली बार चलाने के अंत में, प्रक्रिया 93,388 की स्मृति आकार जानकारी दी है, इसके दूसरे भाग के बाद यह 104,256 जानकारी दी है, केवल स्मृति उपयोग में 10% की वृद्धि के बारे में।

संबंधित मुद्दे