2016-02-11 10 views
5

मेरे पास एक पाइथन स्क्रिप्ट है जो कुछ यूआरएल को स्क्रैप करती है। मेरे पास यूआरएल की एक सूची है और प्रत्येक यूआरएल के लिए मुझे एचटीएमएल मिलता है और इसके साथ कुछ तर्क मिलता है।पायथन लिपि में स्मृति जारी करना

मैं पायथन 2.7.6 और लिनक्स मिंट 17 दालचीनी 64-बिट का उपयोग करता हूं।

समस्या यह है कि स्क्रैपिंग के लिए मेरा मुख्य उद्देश्य, जो कि मैं प्रत्येक यूआरएल के लिए उदाहरण देता हूं, स्मृति से कभी जारी नहीं होता है, हालांकि इसका कोई संदर्भ नहीं है। उस मुद्दे के साथ मेरी याददाश्त बढ़ती जा रही है और तेजी से बढ़ रही है (क्योंकि मेरी वस्तु कभी-कभी बहुत बड़ी होती है - 50 एमबी तक)।

सरल कोड इस तरह दिखता है:

MEMORY USAGE BEFORE SCRAPE: 75732 (kb) 
MEMORY USAGE AFTER SCRAPE: 137392 (kb) 
-------------------------------------------------- 
MEMORY USAGE BEFORE SCRAPE: 137392 (kb) 
MEMORY USAGE AFTER SCRAPE: 206748 (kb) 
-------------------------------------------------- 
MEMORY USAGE BEFORE SCRAPE: 206748 (kb) 
MEMORY USAGE AFTER SCRAPE: 284348 (kb) 
-------------------------------------------------- 

परिमार्जन वस्तु बड़ा है और यह स्मृति से जारी नहीं किया जाता है:

def scrape_url(url): 
    """ 
    Simple helper method for scraping url 
    :param url: url for scraping 
    :return: some result 
    """ 
    scraper = Scraper(url) # instance main Scrape object 
    result = scraper.scrape() # scrape it 

    return result 

## SCRIPT STARTS HERE 
urls = get_urls() # fetch some list of urls 

for url in urls: 
    print 'MEMORY USAGE BEFORE SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    result = scrape_url(url) # call helper method for scraping 
    print 'MEMORY USAGE AFTER SCRAPE: %s (kb)' % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss 
    print '-' * 50 

मेरे उत्पादन कुछ इस तरह है। मैंने कोशिश की:

gc.collect() 

लेकिन कुछ भी मदद की:

scraper = None 

del scraper 

या यहाँ तक कि के साथ वस्तु इकट्ठा करने के लिए जी सी कहते हैं।

जब मैं साथ स्क्रेपर वस्तु के सन्दर्भ की संख्या मुद्रित:

print sys.getrefcount(scraper) 

मैं जो मुझे लगता है कि इसका मतलब है कोई अन्य संदर्भ आपत्ति उठाने का है कि वहाँ और जीसी द्वारा साफ किया जाना चाहिए मिलता है।

स्क्रैपर ऑब्जेक्ट में बहुत से उप-तत्व हैं। यह संभव है कि इसमें से कुछ उप ऑब्जेक्ट का संदर्भ कहीं भी छोड़ा जाए और इसी कारण से जीसी मुख्य स्कैपर ऑब्जेक्ट को रिलीज़ नहीं कर सकता है या कोई और कारण है कि पाइथन मेमोरी जारी नहीं करता है?

मैं अतः में इस बारे में कुछ विषय मिल गया और प्रतिक्रियाओं जहां वे कहते हैं कि स्मृति बात कर रहे हैं में से कुछ जब तक आप बच्चे प्रक्रियाओं जो वास्तव में अजीब लगता है (LINK)

धन्यवाद, इवान

की मौत हो गई/उत्पन्न कर रहे हैं छोड़ा नहीं जा सकता
+1

"स्क्रैपर ऑब्जेक्ट में बहुत से सबबजेक्ट हैं ... स्मृति जारी नहीं करता है?" यह एकमात्र व्यावहारिक कारण होगा। स्क्रैप यूआरएल ने मुझे लगता है कि एक बंदरगाह पर एक कनेक्शन स्थापित किया? शायद उस कनेक्शन में स्थायी संदर्भ है। – user2255757

+0

क्या आप वाकई स्क्रैपर से जुड़े नहीं हैं? – Jerzyk

उत्तर

1

आप एक इटरेटर का उपयोग कर रहे हैं, जो हर समय स्मृति में होना चाहिए। जेनरेटर और आलसी स्क्रैप का उपयोग करने के लिए अपने लूप को फिर से लिखें। कुछ के साथ कुछ:

def gen(): 
     for i in xrange(0, len(urls)): 
      yield urls[i] 
+1

या जनरेटर अभिव्यक्ति जेन = (यूआरएल में यूआरएल के लिए यूआरएल) – Marcin

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