2016-02-11 2 views
5

У меня есть скрипт python, который сбрасывает некоторые URL-адреса. У меня есть список URL-адресов, и для каждого URL-адреса я получаю html и делаю с ним некоторую логику.Освобождение памяти в скрипте python

Я использую Python 2.7.6 и Linux Mint 17 Cinnamon 64-bit.

Проблема заключается в том, что мой основной объект для выскабливания, который я использую для каждого URL-адреса, никогда не освобождается из памяти, хотя на нем нет ссылки. С этой проблемой моя память постоянно растет и быстро растет (поскольку мой объект иногда очень большой - до 50 МБ).

Упростить код выглядит примерно так:

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 

Мой вывод что-то вроде этого:

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 объект является большим, и он не освобожден из памяти. Я пробовал:

scraper = None 

del scraper 

или даже называют дс собирать объект с:

gc.collect() 

, но ничего не помогало.

При печати количество ссылок на объект скребка с:

print sys.getrefcount(scraper) 

Я получаю который я думаю, означает, что нет никаких ссылок на объект и должны быть очищены от дс.

Скребковый объект имеет множество подобъектов. Возможно ли, что некоторые из его ссылок на вспомогательные объекты уходят куда-то и по этой причине gc не может освободить основной объект Scaper или есть какая-то другая причина, по которой python не освобождает память?

Я нашел тему относительно этого в SO и некоторые из ответов, где они говорят, что память не может быть освобожден, если вы не порождая/убийства детей процессы, звучит действительно странно (LINK)

Спасибо, Иван

+1

«Скребок имеет множество подобъектов ... не выпускает память?» это была бы единственная правдоподобная причина. scrape url установил соединение на порт, который я предполагаю? Вероятно, это соединение имеет постоянную ссылку. – user2255757

+0

Вы уверены, что результат не связан с скребком? – Jerzyk

ответ

1

Вы используете итератор, который должен быть в памяти в любое время. Перепишите свою петлю, чтобы использовать генератор и лениво царапать. Что-то по строкам:

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

или выражение генератора с gen = (url для url в URL-адресах) – Marcin

Смежные вопросы