2013-03-01 5 views
1

У меня проблема с сценарием большого тиража. Этот скрипт является многопоточной средой для выполнения задач сканирования.Python: как мусор собирать строки

В больших исполнениях потребление памяти сценария становится огромным, и после профилирования памяти с помощью guppy hpy я увидел, что большая часть проблемы поступает по строкам.

Я не храню столько строк: просто получайте содержимое htmls в память, чтобы хранить их в db. После этого строка больше не используется (переменная, содержащая ее, назначается следующей строке).

Проблема возникла из-за того, что я видел, что каждая новая строка (с sys.getrefcount) имеет, по крайней мере, 2 ссылки (1 из моего var и 1 внутренний). Кажется, что переназначение другого значения для моего var не удаляет внутреннюю ссылку, поэтому строка остается в памяти.

Что я могу сделать, чтобы убедиться, что строки собраны в мусор?

Спасибо заранее

EDIT:

1- Я использую Django ORM

2- я получить все эти строки из 2-х источников:

2.1- Непосредственно из сокета (urllib2.urlopen (url) .read())

2.2- Разбор ответов и выдача новых URI из каждой системы html и подачи

SOLVED

Наконец-то я получил ключ. Сценарий является частью среды Django, и кажется, что подпольная группа Django делает кеш или что-то подобное. Я отключил отладку, и все начали работать, как ожидалось (повторное использование отступов, похоже, удаляет ссылки на старые объекты, а объекты собираются gc).

Для тех, кто использует какое-то рамка слоя над питоном, быть в курсе конфигурации: кажется, что некоторые отладочные конфигурации с интенсивным процессом может привести к утечке памяти

+0

Вы попробовали del (my_str_var)? – Marat

+0

если 'sys.getrefcount' возвращает 2, тогда нет внутренней ссылки, потому что когда вы передаете объект' sys.getrefcount'. Это увеличит количество ссылок. – HYRY

+0

Я просто назначаю новые строки старым vars. Очевидно, я доверял сборщику мусора у питонов, но, похоже, этого недостаточно. Попробует добавить «del» в каждом строчном вызове – user989501

ответ

0

Вы должны были бы выяснить, кто держит «внутренний "ссылка на ваши строки. Возможно, библиотека, которую вы используете для записи в БД (вы не указали, как вы пишете в БД). Я нахожу objgraph очень полезным для таких задач: https://pypi.python.org/pypi/objgraph

E.g.

import objgraph 
objgraph.show_backrefs([mystring], filename='a.png') 
+0

Я использовал objgraph, но не могу получить информацию о строках (он не отслеживает информацию об объектах, которые называют «простой», как ints или строки). – user989501

1

Вы говорите:
Я видел, что каждая новая строка (с sys.getrefcount) имеют, по крайней мере, 2 ссылки

Но вы внимательно прочитали описание getrefcount()? :

sys.getrefcount()

объект) Возвращает счетчик ссылок объекта. Возвращаемый счетчик , как правило, выше, чем вы могли ожидать, поскольку он содержит ссылку (временную) в качестве аргумента для getrefcount().

.

Вам следует больше объяснить вашу программу.

Каков размер строк HTML, которые он содержит?
Как они получены? Вы действительно хотите закрыть все обработчики файлов, все сокеты, ...?

+0

Размер HTML произволен (некоторые из них короткие, некоторые огромные). Я получаю его, сохраняю в переменной объекта, обрабатываю весь объект, а затем удаляю объект. Никакого исключения не было, чтобы позволить объекты со ссылками (я отслеживал это), но у меня все еще есть все больше и больше строк в системе (отслеживается с помощью guppy heapy), в то время как я повторно использую все свои vars – user989501

+0

@ user989501 Я имею в виду, что никакой доступный объект в Python не заслуживает называться «переменная». (Есть базовые указатели, которые являются реальными переменными, но они недоступны) – eyquem

+0

Я думаю, что любой, у кого есть язык программирования (на любом языке), может понять смысл «переменной» и может понимать перевод в среду python (некоторый идентификатор, который ссылается на что-то в памяти). Я не думаю, что мои слова могут ввести в заблуждение кого-то, чтобы подумать о другом, что идентификаторы python – user989501