2011-06-11 8 views
10

एसओ में पाइथन कचरा संग्रह पर कई धागे हैं, और लगभग पांच पढ़ने के बाद, लाइन पर कुछ दस्तावेज़ पढ़ने के बाद भी, मुझे अभी भी यकीन नहीं है कि कैसे कचरा संग्रह काम करता है और मुझे उन वस्तुओं का प्रबंधन कैसे करना चाहिए जिन्हें मैं उपयोग नहीं कर रहा हूं। असल में मैंने कहीं पढ़ा है कि कचरा इकट्ठा करने के बारे में कुछ भी नहीं करना चाहिए, अन्य लोगों को बताएं कि del ऑब्जेक्ट्स चाहिए, जबकि अन्य ने फिर से ऑब्जेक्ट को डी-रेफरेंसिंग करने की व्याख्या की है ताकि पाइथन इसे कचरा के रूप में इकट्ठा कर सके।ऑब्जेक्ट को पाइथन कचरा संग्रह में कैसे पहुंचाया जाए?

तो, डुप्लिकेट बनाने के जोखिम पर, मैं फिर से प्रश्न पूछूंगा, लेकिन अलग-अलग, अधिक व्यापक और स्पष्ट जानकारी प्राप्त करने की उम्मीद कर रहा हूं।

मेरे मामले में मैं लोगों का प्रतिनिधित्व करने वाली वस्तुओं के साथ एक छोटा सिमुलेशन बनाना चाहता हूं। Person() कक्षा के कई उदाहरण बनाए जाएंगे। यह कुछ समय तक अस्तित्व में होना चाहिए जब तक कि यह लगभग "मर जाता है" जबकि अन्य उदाहरण बनाए जाएंगे।

अब मैं यह Person() उदाहरण "मर" कैसे बना सकता हूं (मानते हैं कि इनमें से कई उदाहरण बनाए जाएंगे और मैं नहीं चाहता कि ये उदाहरण भूत की तरह लटक जाएं)?

ऐसे कई तरीके है मैं एक वस्तु को संदर्भित कर सकते हैं:

john = Person('john') 

या

people = [] 
people.append(Person('john')) 

या

people = {} 
people['john'] = Person('john') 

सबसे अच्छा तरीका क्या मेरा कार्यक्रम स्वच्छ, मुक्त कराने के संसाधनों को रखने के लिए है बेहतर? और फिर मेरे ऑब्जेक्ट को संदर्भित करने का सबसे अच्छा तरीका क्या है ताकि मैं ऑब्जेक्ट को हटाने पर नियंत्रण कर सकूं?

+0

जीसी मॉड्यूल की जांच करें: http://docs.python.org/library/gc.html – rubik

+1

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

+0

यह प्रश्न रूबी, स्मॉलटाक, जावा, सी # या वीबी 6 और शायद कई अन्य लोगों पर भी लागू हो सकता है। – quamrana

उत्तर

4

मुझे लगता है कि अधिकांश कार्यक्रम वस्तुओं को बहुत स्वाभाविक रूप से बनाते हैं और उनका निपटान करते हैं, इसलिए मैं कभी भी इसके बारे में सामान्य रूप से चिंता नहीं करता हूं।

कुछ उदाहरण:

people = {} 
people['john'] = Person('john') 

def removePerson(personName): 
    del people[personName] 

removePerson('john') 

इस मामले people में मास्टर सूची है और जब एक Person जोड़ा और से हटा दिया जाता है जिसे आप नियंत्रित कर सकते हैं:

person = Person('john') 
person = Person('james') 
# Whoops! 'john' has died! 

people = [] 
people.append(Person('john')) 
# ... 
# All 'Persons' live in people 
people = [] 
# Now all 'Persons' are dead (including the list that referenced them) 

class House(): 
    def setOwner(self, person): 
     self.owner = person 

house.setOwner(people[0]) 
# Now a House refers to a Person 
people = [] 
# Now all 'Persons' are dead, except the one that house.owner refers to. 

मैं क्या मान लें कि आपके बाद कर रहे हैं यह है सूची (इसका एक शब्दकोश)।

आपको किसी व्यक्ति की अवधारणा के माध्यम से सोचना पड़ सकता है और फिर बहुत अच्छी तरह से मर रहा है: एक बार बनाया गया कि व्यक्ति पहले सिमुलेशन के साथ कैसे सहभागिता करता है। मौत पर, आप संदर्भों को कैसे उलझा सकते हैं? (किसी व्यक्ति के लिए अन्य सामानों का संदर्भ देना ठीक है, इसकी चीजें House जैसे मेरे उदाहरण में एक व्यक्ति को जिंदा रखेगी। आप अन्य वस्तुओं को केवल व्यक्ति के नाम पर रख सकते हैं)।

+0

इस के लिए धन्यवाद :) – Benjamin

7

इनमें से कोई भी वास्तव में कचरा संग्रह के साथ कुछ भी करने के लिए नहीं है।

पाइथन की स्मृति प्रबंधन का मुख्य तरीका संदर्भ गणना का उपयोग करता है।

उपर्युक्त सभी मामलों में, पाइथन ऑब्जेक्ट के सभी संदर्भों की गिनती रखता है, और जब कोई नहीं छोड़ा जाता है, तो वस्तु हटा दी जाती है (std::shared_pointer सी ++ में)।

संदर्भ में कमी आई जब

  1. वस्तु धारण उन्हें या तो स्पष्ट रूप नष्ट कर दिया (del के माध्यम से)
  2. है या गुंजाइश (see also here (esp. ex. 8)) के बाहर चला जाता है मिलता है।

आपके मामले में, यह john ऑब्जेक्ट, या people कंटेनर में से किसी पर लागू होता है। वे उस समारोह के अंत में गुंजाइश से बाहर निकलते हैं जो उन्हें बनाया गया है (मानते हैं कि वे कॉलिंग फ़ंक्शन पर return एड नहीं हैं)। उस समय के विशाल बहुमत, आप उन्हें केवल दायरे से बाहर जाने दे सकते हैं - यह केवल तभी होता है जब आप वास्तव में भारी वस्तुएं या संग्रह बनाते हैं - एक बड़े पाश के अंदर कहें - कि आप स्पष्ट रूप से del का उपयोग करने पर विचार करना चाहेंगे।उदाहरण के लिए, जब एक वस्तु ही को संदर्भित करता है - जब वहाँ संदर्भ चक्र हैं

कचरा संग्रहण वास्तव में केवल खेलने में आता है। पसंद:

a = [] 
a.append(a) 

फिर, यह स्वचालित रूप से होता है, और आपको कुछ विशेष करने की आवश्यकता नहीं है।

+0

धन्यवाद :) सभी उत्तरों वास्तव में अच्छे थे, मैंने क्वात्राना को उठाया क्योंकि उन्होंने एक ऐसा उत्तर दिया जो प्रश्न के उदाहरण के साथ अधिक संगत था। – Benjamin

9

हो सकता है कि यह भी मदद कर सकते हैं:

>>> # Create a simple object with a verbose __del__ to track gc. 
>>> class C: 
...  def __del__(self): 
...   print "delete object" 
... 
>>> c = C() 
>>> # Delete the object c successfully. 
>>> del c 
delete object 
>>> # Deletion of an object when it go out of the scope where it was defined. 
>>> def f(): 
...  c = C() 
... 
>>> f() 
delete object 
>>> c = C() 
>>> # Create another reference of the object. 
>>> b = c 
>>> # The object wasn't destructed the call of del only decremented the object reference. 
>>> del c 
>>> # Now the reference counter of the object reach 0 so the __del__ was called. 
>>> del b 
delete object 
>>> # Create now a list that hold all the objects. 
>>> l = [C(), C()] 
>>> del l 
delete object 
delete object 
>>> # Create an object that have a cyclic reference. 
>>> class C: 
...  def __init__(self): 
...   self.x = self 
...  def __del__(self): 
...   print "delete object" 
... 
>>> c = C() 
>>> # Run the garbage collector to collect object. 
>>> gc.collect() 
9 
>>> # the gc.garbage contain object that the gc found unreachable and could not be freed. 
>>> gc.garbage 
[<__main__.C instance at 0x7ff588d84368>] 
>>> # Break the cyclic reference. 
>>> c.x = None 
>>> # And now we can collect this object. 
>>> del c 
delete object 
>>> # Create another object with cyclic reference. 
>>> c = C() 
>>> # When closing the interactive python interpreter the object will be collected. 
delete object 

refrences: del method; gc module; weakref module

+0

धन्यवाद :) सभी उत्तरों वास्तव में अच्छे थे, मैंने क्वात्राना को उठाया क्योंकि उन्होंने एक ऐसा उत्तर दिया जो प्रश्न के उदाहरण के साथ अधिक संगत था। – Benjamin

+0

@ बेंजामिन: खुशी है कि आपको अपना जवाब मिल गया :) – mouad

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