2013-06-10 5 views
5

Ich habe ein sehr einfaches Python-Skript mit gevent.pool zum Download von URLs (siehe unten). Das Skript läuft einige Tage einwandfrei und stürzt dann ab. Ich habe bemerkt, dass der Speicherverbrauch zu dieser Zeit sehr hoch ist. Benutze ich Gevent falsch?Python-Skript mit Gevent-Pool, verbraucht viel Speicher, stört

import sys 

from gevent import monkey 
monkey.patch_all() 
import urllib2 

from gevent.pool import Pool 

inputFile = open(sys.argv[1], 'r') 
urls = [] 
counter = 0 
for line in inputFile: 
    counter += 1 
    urls.append(line.strip()) 
inputFile.close() 

outputDirectory = sys.argv[2] 

def fetch(url): 
    try: 
     body = urllib2.urlopen("http://" + url, None, 5).read() 
     if len(body) > 0: 
      outputFile = open(outputDirectory + "/" + url, 'w') 
      outputFile.write(body) 
      outputFile.close() 
      print "Success", url 
    except: 
     pass 

pool = Pool(int(sys.argv[3])) 
pool.map(fetch, urls) 
+0

Klingt wie ein Speicherleck in 'gevent'. Eine schnelle Suche nach 'python gevent memory leak' führt zu einer überraschend großen Anzahl von Treffern, obwohl Sie wahrscheinlich in einer besseren Position sind, um festzustellen, ob sie für Ihren speziellen Fall zutreffen. – Aya

Antwort

2
 body = urllib2.urlopen("http://" + url, None, 5).read() 

Above Linie liest den gesamten Inhalt im Speicher als String zurück. Um dies zu verhindern, ändern Sie fetch() wie folgt:

def fetch(url): 
    try: 
     u = urllib2.urlopen("http://" + url, None, 5) 
     try: 
      with open(outputDirectory + "/" + url, 'w') as outputFile: 
       while True: 
        chunk = u.read(65536) 
        if not chunk: 
         break 
        outputFile.write(chunk) 
     finally: 
      u.close() 
     print "Success", url 
    except: 
     print "Fail", url 
+0

mit open (...) als outputFile ... statt zu versuchen – zinking

Verwandte Themen