2012-09-14 10 views
17

कई मामलों में, आप सुनिश्चित करें कि आप निश्चित रूप से फिर से सूची का उपयोग नहीं होगा, मैं आशा है कि स्मृति को रिहा किया जाना चाहिए अभीपाइथन सूची में तुरंत उपयोग की गई स्मृति को कैसे रिलीज़ करें?

a = [11,22,34,567,9999] 
del a 

मैं यकीन नहीं करता है, तो यह वास्तव में स्मृति को रिहा कर रहे हैं, तो आप उपयोग कर सकते हैं

del a[:] 

जो वास्तव में सूची में सभी तत्वों को हटा देता है।

तो रिलीज़ करने का सबसे अच्छा तरीका यह है?

def realse_list(a): 
    del a[:] 
    del a 

आपकी राय नहीं है।

बीटीडब्ल्यू, टुपल और सेट के बारे में कैसे?

+9

जब तक कि आप बहुत से डेटा से निपट नहीं रहे हैं और वास्तव में मेमोरी एरर अपवाद प्राप्त कर रहे हैं, तो स्मृति प्रबंधन के बारे में चिंता न करें। – monkut

उत्तर

19
def release_list(a): 
    del a[:] 
    del a 

ऐसा नहीं कभी करें। पाइथन स्वचालित रूप से उन सभी ऑब्जेक्ट्स को मुक्त करता है जिन्हें संदर्भित नहीं किया जाता है, इसलिए एक सरल del a यह सुनिश्चित करता है कि सूची की स्मृति कहीं भी संदर्भित नहीं होने पर सूची की स्मृति जारी की जाएगी। यदि ऐसा है, तो अलग-अलग सूची आइटम भी जारी किए जाएंगे (और केवल उन वस्तुओं से संदर्भित किया गया है, और इसी तरह से), जब तक कि कुछ अलग-अलग वस्तुओं को अभी भी संदर्भित नहीं किया जाता है।

इसका मतलब है कि केवल समय था जब del a[:]; del a अपने आप ही एक से अधिक del a जारी करेंगे जब सूची कहीं और संदर्भित किया जाता है। यह ठीक है जब आप सूची को खाली नहीं करना चाहिए: कोई और अभी भी इसका उपयोग कर रहा है !!!

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

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

+0

क्या ** ** ** एक सदस्य चर (एक बड़ा) है और मुझे पता है कि मैं अब इसका उपयोग नहीं करूँगा, क्या यह "संदर्भित चर" के रूप में गिना जाता है? परिदृश्य सरल है: मेरे पास एक ऑब्जेक्ट है जो एक बड़ी सूची _when_needed_ को संसाधित करता है। कुछ विधि कहने के बाद, ** एक ** सूची संसाधित की जाती है और मैं परिणाम कैश करता हूं। इस मामले में मुझे पता है कि मुझे अब ** ** की आवश्यकता नहीं होगी। – hsgubert

+1

@hsgubert अगर 'a' किसी ऑब्जेक्ट (सदस्य चर) की विशेषता है, तो हां इसे उस ऑब्जेक्ट का हिस्सा होने के संदर्भ में संदर्भित किया जाता है (माना जाता है कि ऑब्जेक्ट को कहीं संदर्भित किया गया है)। लेकिन अगर आपको पता है कि आपको अब इसकी आवश्यकता नहीं है और आप उसी कक्षा के तरीके में हैं, तो आप इससे छुटकारा पाने के लिए 'del self.a' कर सकते हैं। यदि आप उस वर्ग की विधि में नहीं हैं, तो इसके साथ गड़बड़ न करें। अच्छी डिजाइन लगभग हर वर्ग को अपने गुणों के प्रबंधन के लिए जिम्मेदार रखती है; यदि कक्षा के * अन्य * भाग यादृच्छिक रूप से तय कर सकते हैं कि किसी ऑब्जेक्ट को इसके गुणों में से किसी एक की आवश्यकता नहीं है, तो कक्षा को समझना बहुत मुश्किल है। – Ben

4

@monkut नोट्स के रूप में, आपको शायद अधिकांश स्थितियों में स्मृति प्रबंधन के बारे में बहुत चिंता नहीं करनी चाहिए।

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

इस वजह से, del a आपके realse_list फ़ंक्शन में कथन वास्तव में कुछ भी नहीं करता है, क्योंकि कॉलर के पास अभी भी एक संदर्भ है!

del a[:], जैसा कि आप ध्यान दें, सूची से तत्वों को हटा दें और इस प्रकार शायद इसकी अधिकांश मेमोरी उपयोग हटा दें।

आप सेट के साथ समान व्यवहार के लिए the_set.clear() कर सकते हैं।

आप एक टुपल के साथ कर सकते हैं, क्योंकि वे अपरिवर्तनीय हैं, del the_tuple है और उम्मीद है कि किसी और के पास इसका कोई संदर्भ नहीं है - लेकिन आपको शायद भारी tuples नहीं होना चाहिए!

+1

यह उत्तर कमजोर संदर्भों की चर्चा के साथ काफी अधिक पूर्ण होगा। – Marcin

1

यदि आप डेटा प्रबंधन के लिए स्मृति प्रबंधन और प्रदर्शन के बारे में चिंतित हैं तो क्यों एक लिंक की गई डबल कतार की तरह कुछ उपयोग नहीं करते हैं।

सबसे पहले इसकी स्मृति पदचिह्न स्मृति के बावजूद बिखरी हुई है, इसलिए आपको बल्ले से लगातार लगातार स्मृति का एक बड़ा हिस्सा आवंटित नहीं करना पड़ेगा।

दूसरा आपको एनक्यूइंग और डेक्यूइंग के लिए तेज़ एक्सेस समय दिखाई देगा क्योंकि जब आप हटाते हैं तो एक मानक सूची के विपरीत एक मध्यम तत्व कहता है, सूची में शेष सूची को स्लाइड करने की कोई आवश्यकता नहीं है, जिसमें बड़ी सूचियों में समय लगता है ।

मुझे यह भी ध्यान रखना चाहिए कि क्या आप केवल पूर्णांक का उपयोग कर रहे हैं, मैं एक बाइनरी ढेर में देखने का सुझाव दूंगा क्योंकि आप ओ (लॉग^2 एन) एक्सेस टाइम्स को ज्यादातर ओ (एन) की तुलना में सूचियों के साथ देखेंगे।

2

पायथन अपने संसाधन का प्रबंधन करने के लिए Reference Count का उपयोग करता है।

import sys 
class foo: 
    pass 

b = foo() 
a = [b, 1] 

sys.getrefcount(b) # gives 3 
sys.getrefcount(a) # gives 2 

a = None # delete the list 
sys.getrefcount(b) # gives 2 

उपरोक्त उदाहरण में, ख के संदर्भ गिनती बढ़ती जाएगा जब आप इसे एक सूची में डाल दिया, और जैसा कि आप देख सकते हैं, जब आप सूची को हटाने, ख के संदर्भ संख्या बहुत कम कर मिलता है। तो आपके कोड में

def release_list(a): 
    del a[:] 
    del a 

अनावश्यक था।

संक्षेप में, आपको केवल किसी भी वस्तु में सूची निर्दिष्ट करने या विशेषता शब्दकोश से सूची को हटाने के लिए डेल कीवर्ड का उपयोग करने की आवश्यकता है। (ए.के.ए., वास्तविक वस्तु से नाम को अनबाइंड करने के लिए)। उदाहरण के लिए,

a = None # or 
del a 

जब किसी ऑब्जेक्ट की संदर्भ संख्या शून्य हो जाती है, तो पाइथन आपके लिए स्मृति मुक्त कर देगा। यह सुनिश्चित करने के लिए कि ऑब्जेक्ट हटा दिया गया है, आपको यह सुनिश्चित करना होगा कि कोई अन्य स्थान ऑब्जेक्ट को नाम या कंटेनर द्वारा संदर्भित न करे।

sys.getrefcount(b) # gives 2 

हैं sys.getrefcount आप 2 देता है, इसका मतलब है कि आप केवल एक है जो वस्तु के संदर्भ था कर रहे हैं और जब आप

b = None 

कर यह स्मृति से मुक्त हो जाएगा।

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