कृपया बेहतर समाधान के लिए @joeblog द्वारा अगले जवाब देखते हैं।
सबसे पहले, आपको पहले स्थान पर सभी रैम की आवश्यकता नहीं होनी चाहिए। आपको यहां क्या करना चाहिए, परिणाम सेट के भाग ला रहा है। fetchall()
मत करो। इसके बजाय, अधिक कुशल cursor.fetchmany
विधि का उपयोग करें। the psycopg2 documentation देखें।
अब, स्पष्टीकरण क्यों है कि इसे मुक्त नहीं किया गया है, और यह उस शब्द के औपचारिक रूप से सही उपयोग में स्मृति रिसाव क्यों नहीं है।
अधिकांश प्रक्रियाएं ओएस को वापस मुक्त होने पर स्मृति को रिलीज़ नहीं करती हैं, वे इसे प्रोग्राम में कहीं और फिर से उपयोग के लिए उपलब्ध कराते हैं।
मेमोरी केवल ओएस को रिलीज़ किया जा सकता है यदि प्रोग्राम मेमोरी के माध्यम से बिखरी हुई शेष वस्तुओं को कॉम्पैक्ट कर सकता है। यह केवल तभी संभव है जब अप्रत्यक्ष हैंडल संदर्भों का उपयोग किया जाता है, क्योंकि अन्यथा किसी ऑब्जेक्ट को स्थानांतरित करने से ऑब्जेक्ट में मौजूदा पॉइंटर्स को अमान्य कर दिया जाएगा। अप्रत्यक्ष संदर्भ बल्कि अक्षम हैं, खासतौर पर आधुनिक सीपीयू पर जहां प्रदर्शन करने के लिए भयानक चीजें हैं।
प्रोग्राम द्वारा अतिरिक्त सावधानी बरतने तक आम तौर पर तब तक क्या हो रहा है जब brk()
के साथ आवंटित स्मृति का प्रत्येक बड़ा हिस्सा अभी भी उपयोग में आने वाले कुछ छोटे टुकड़ों के साथ उतरा है।
ओएस यह नहीं बता सकता कि प्रोग्राम इस स्मृति को अभी भी उपयोग में रखता है या नहीं, इसलिए यह केवल इसका दावा नहीं कर सकता है। चूंकि प्रोग्राम मेमोरी तक नहीं पहुंचता है, इसलिए ओएस आमतौर पर समय के साथ इसे स्वैप कर देगा, अन्य उपयोगों के लिए भौतिक स्मृति मुक्त कर देगा। स्वैप स्पेस होने के कारणों में से एक यह है।
प्रोग्राम लिखना संभव है जो स्मृति को ओएस पर वापस रखता है, लेकिन मुझे यकीन नहीं है कि आप इसे पायथन के साथ कर सकते हैं।
यह भी देखें:
तो: यह नहीं वास्तव में एक स्मृति रिसाव है। यदि आप कुछ और काम करते हैं जो बहुत सारी मेमोरी का उपयोग करता है, तो प्रक्रिया को बहुत अधिक नहीं बढ़ना चाहिए, यह पिछले बड़े आवंटन से पूर्व मुक्त स्मृति का पुन: उपयोग करेगा।
स्रोत
2013-06-20 01:20:53
धन्यवाद! पुष्टि की है कि उपरोक्त कोड को एक ही प्रक्रिया में दो बार चलाकर स्मृति का पुन: उपयोग किया जाता है। दूसरे रन के दौरान मेमोरी में वृद्धि नहीं हुई। –
जबकि सबकुछ यहां कहा गया है, एक सामान्य परिणाम सामान्य रूप से ग्राहक पक्ष पर स्थानांतरित किया जाएगा ('fetch *() 'द्वारा नहीं बल्कि' execute() ')। तो 'fetchall() 'के बजाय' fetchmany() 'का उपयोग करते समय पाइथन ऑब्जेक्ट सृजन के मामले में कुछ मेमोरी सहेज सकते हैं, सर्वर-साइड कर्सर का उपयोग करके @joeblog द्वारा सुझाया गया सही समाधान है। – piro