Ich habe ein Python-Skript, das einige URLs kratzt. Ich habe eine Liste von URLs und für jede URL bekomme ich HTML und mache ein wenig Logik damit.Freigabe von Speicher in Python-Skript
Ich benutze Python 2.7.6 und Linux Mint 17 Cinnamon 64-Bit.
Problem ist, dass mein Hauptobjekt für Scraping, das ich für jede URL instanziiere, nie aus dem Speicher freigegeben wird, obwohl es keinen Verweis darauf gibt. Mit diesem Problem wächst und wächst mein Gedächtnis schnell (da mein Objekt manchmal sehr groß ist - bis zu 50MB).
Vereinfachen Code sieht etwa so aus:
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
Meine Ausgabe ist so etwas wie diese:
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)
--------------------------------------------------
Scrape Objekt ist groß und es ist nicht aus dem Speicher freigegeben. Ich habe versucht:
scraper = None
del scraper
oder sogar gc rufen mit dem Objekt zu sammeln:
gc.collect()
aber nichts half.
Wenn ich Reihe von Verweisen auf Schaber Objekt drucken mit:
print sys.getrefcount(scraper)
bekomme ich die ich denke, bedeutet, dass es keine anderen Verweise Objekt und sollte von gc gereinigt werden.
Scraper-Objekt hat viele Unterobjekte. Ist es möglich, dass einige der Sub-Objekt-Referenzen irgendwo liegen bleiben und aus diesem Grund kann gc das Haupt-Scaper-Objekt nicht freigeben oder gibt es einen anderen Grund, warum Python keinen Speicher freigibt?
fand ich einige Thema in Bezug auf diese in SO und einige der Antworten, wo sie diese Erinnerung sprechen kann nicht freigegeben werden, wenn Sie untergeordnete Prozesse/Tötung laichen, die wirklich seltsam klingt (LINK)
Danke, Ivan
"Scraper-Objekt hat viele Unterobjekte ... gibt Speicher nicht frei?" das wäre der einzig plausible Grund. scrape url stellte eine Verbindung auf einem Port her, nehme ich an? Wahrscheinlich hält diese Verbindung die stehende Referenz. – user2255757
Sind Sie sicher, dass das Ergebnis nicht mit Scrapper verbunden ist? – Jerzyk