मेरे पास एक सरल ActiveRecord मॉडल है जिसे तालिका में 100 रिकॉर्ड के साथ Student
कहा जाता है। मैं एक रेल कंसोल सत्र में निम्नलिखित है:हैश में ActiveRecord ऑब्जेक्ट्स कचरा नहीं एकत्रित हैं - एक बग या कैशिंग सुविधा का एक प्रकार?
ObjectSpace.each_object(ActiveRecord::Base).count
# => 0
x = Student.all
ObjectSpace.each_object(ActiveRecord::Base).count
# => 100
x = nil
GC.start
ObjectSpace.each_object(ActiveRecord::Base).count
# => 0 # Good!
अब मैं निम्नलिखित है:
ObjectSpace.each_object(ActiveRecord::Base).count
# => 0
x = Student.all.group_by(&:last_name)
ObjectSpace.each_object(ActiveRecord::Base).count
# => 100
x = nil
GC.start
ObjectSpace.each_object(ActiveRecord::Base).count
# => 100 # Bad!
किसी को भी व्याख्या कर सकते हैं कि ऐसा क्यों होता है और वहाँ अंतर्निहित जानने के बिना इस समस्या के समाधान के लिए एक स्मार्ट तरीका है कि क्या हैश संरचना? मैं जानता हूँ कि मैं यह कर सकता:
x.keys.each{|k| x[k]=nil}
x = nil
GC.start
और इसे सही ढंग स्मृति से सभी छात्र वस्तुओं को हटाने जाएगा, लेकिन अगर वहाँ एक सामान्य समाधान है मैं सोच रहा हूँ (मेरे वास्तविक जीवन समस्या व्यापक प्रसार है और अधिक जटिल डेटा है ऊपर दिखाए गए हैश की तुलना में संरचनाएं)।
मैं रूबी 1.9.3-पी 0 और रेल 3.1.0 का उपयोग कर रहा हूं।
अद्यतन (हल)
नीचेप्रति ऑस्कर डेल बेन विवरण, कुछ ActiveRecord :: संबंध वस्तुओं (वे वास्तव में दोनों कोड के टुकड़े में बनाए गए हैं, लेकिन समस्या पैदा करने वाले कोड स्निपेट में बनाए जाते हैं किसी कारण से वे केवल दूसरे में "दुर्व्यवहार"। क्या कोई प्रकाश पर प्रकाश डाल सकता है?)। ये ActiveRecord ऑब्जेक्ट्स के संदर्भ को एक आवृत्ति चर के माध्यम से @records कहते हैं। यह आवृत्ति चर ActiveRecord :: संबंध पर "रीसेट" विधि के माध्यम से शून्य पर सेट किया जा सकता है। आप सभी संबंध वस्तुओं पर इस प्रदर्शन करने के लिए सुनिश्चित करने के लिए है:
ObjectSpace.each_object(ActiveRecord::Base).count
# => 100
ObjectSpace.each_object(ActiveRecord::Relation).each(&:reset)
GC.start
ObjectSpace.each_object(ActiveRecord::Base).count
# => 0
ध्यान दें: आपके, (ruby-mass मणि ऑस्कर डेल बेन संदर्भित का प्रयोग करके) Mass.detach उपयोग कर सकते हैं, हालांकि यह कोड तुलना में बहुत धीमी हो जाएगा ऊपर। ध्यान दें कि उपरोक्त कोड स्मृति से कुछ ActiveRecord :: संबंध ऑब्जेक्ट्स को नहीं हटाता है। हालांकि ये बहुत महत्वहीन प्रतीत होता है। आप कर कोशिश कर सकते हैं:
Mass.index(ActiveRecord::Relation)["ActiveRecord::Relation"].each{|x| Mass.detach Mass[x]}
GC.start
और यह ActiveRecord :: संबंध वस्तुओं में से कुछ को दूर होता है, लेकिन उन सभी को नहीं (यकीन नहीं क्यों, और उन है कि छोड़ दिया जाता है कोई Mass.references अजीब है।)।
1.9 या 3.1 के लिए अद्वितीय हो सकता है - मैं इस व्यवहार को रेल 3.0.7 और रूबी एंटरप्राइज़ (री 1.8.7) के साथ नहीं देख रहा हूं। – klochner
धन्यवाद Klochner! मैंने बस रुबी 1.8.7-पी 174 के तहत कोड चलाया। ऐसा लगता है कि रूबी 1.8.7 रेल 3.0.7 और रेल 3.1.0 दोनों पर ऑब्जेक्ट विनाश को सही तरीके से संभालती है। अर्थात। दूसरे उदाहरण में मुझे 0 ऑब्जेक्ट्स मिलते हैं। मैंने रुबी 1.9.2 की भी कोशिश की, और एक ही समस्या 1.9.3 के साथ होती है। क्या आपको लगता है कि YARV में एक बग है? – AmitA
मैंने रूबी 1.8.7 और रेल 2.3.12 के साथ एक परीक्षण चलाया। मैंने केवल कंसोल में परीक्षण किया और एक ही समस्या थी। ** ** को छोड़कर, जब मैंने 'नेमसर्सा' को कंसोल में कचरा लिखा था, तो 'नेमएरर'' शुरू करने के लिए। इस 'जीसी.स्टार्ट' के बाद सबकुछ साफ हो गया। निश्चित नहीं है कि सिर्फ एक उत्सुक दुष्प्रभाव या कुछ और महत्वपूर्ण है। – Casper