Ho uno script python che cancella alcuni URL. Ho una lista di URL e per ogni URL ottengo html e faccio un po 'di logica con esso.Rilascio di memoria in script python
Io uso Python 2.7.6 e Linux Mint 17 Cinnamon 64-bit.
Il problema è che il mio oggetto principale per lo scraping, quale istanza per ogni url, non viene mai rilasciato dalla memoria sebbene non ci sia riferimento ad esso. Con questo problema la mia memoria continua a crescere e crescere rapidamente (dal momento che il mio oggetto è talvolta molto grande - fino a 50 MB).
codice Semplificare simile a questa:
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
La mia uscita è qualcosa di simile:
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)
--------------------------------------------------
Raschiare oggetto è grande e non è rilasciato dalla memoria. ho provato:
scraper = None
del scraper
o anche chiamare GC per raccogliere oggetto con:
gc.collect()
ma non serviva a niente.
Quando stampo numero di riferimenti a oggetto raschietto con:
print sys.getrefcount(scraper)
ottengo che secondo me significa che non ci sono altri riferimenti a oggetto e deve essere pulita da GC.
L'oggetto raschietto ha molti sottooggetti. È possibile che alcuni di essi vengano lasciati da qualche parte e per questo motivo gc non può rilasciare l'oggetto Scaper principale o c'è qualche altra ragione per cui Python non rilascia la memoria?
ho trovato qualche argomento per quanto riguarda questo in SO e alcune delle risposte in cui stanno parlando che la memoria non può essere rilasciato a meno che non stanno deponendo le uova/uccidere i processi figli che suona davvero strano (LINK)
Grazie, Ivan
"L'oggetto raschietto ha molti sottooggetti ... non rilascia memoria?" questa sarebbe l'unica ragione plausibile. urlo di scrap ha stabilito una connessione su una porta presumo? Probabilmente quella connessione mantiene il riferimento permanente. – user2255757
sei sicuro che il risultato non è connesso con lo scrapper? – Jerzyk