парсер lxml пожирает всю память - PullRequest
12 голосов
/ 10 марта 2011

Я пишу несколько пауков в python и использую библиотеку lxml для анализа html и библиотеку gevent для асинхронного.Я обнаружил, что после некоторого времени работы lxml parser начинает кушать память до 8 Гб (вся память сервера).Но у меня есть только 100 асинхронных потоков, каждый из которых анализирует документ максимум до 300 КБ.

Я протестировал, и эта проблема начинается в lxml.html.fromstring, но я не могу воспроизвести эту проблему.

Проблема в этой строке кода:

HTML = lxml.html.fromstring(htmltext)

Может быть, кто-то знает, что это может быть, или как это исправить?

Спасибо за помощь.

PS

Linux Debian-50-lenny-64-LAMP 2.6.26-2-amd64 #1 SMP Tue Jan 25 05:59:43 UTC 2011 x86_64    GNU/Linux
Python : (2, 6, 6, 'final', 0)
lxml.etree : (2, 3, 0, 0)
libxml used : (2, 7, 8)
libxml compiled : (2, 7, 8)
libxslt used : (1, 1, 26)
libxslt compiled : (1, 1, 26)

UP:

я установил ulimit -Sv 500000 и uliit -Sm 615000 для процессов, использующих анализатор lxml.

А теперьчерез некоторое время они начинают записывать в журнал ошибок:

«Исключение MemoryError: MemoryError () в lxml.etree._BaseErrorLog._receive« ignored ».

И я не могу поймать это исключение, поэтому оно рекурсивно записывает в журнал это сообщение, пока на диске нет свободного места.

Как мне перехватить это исключение, чтобы уничтожить процесс, чтобы демон мог создать новоеодин ??

Ответы [ 3 ]

7 голосов
/ 10 марта 2011

Возможно, вы сохраняете некоторые ссылки, которые поддерживают работу с документами.Будьте осторожны со строковыми результатами оценки xpath, например: по умолчанию они являются «умными» строками, которые обеспечивают доступ к содержащему элементу, таким образом сохраняя дерево в памяти, если вы сохраняете ссылку на них.См. Документы по возвращаемым значениям xpath :

В некоторых случаях поведение смарт-строки нежелательно.Например, это означает, что дерево будет поддерживаться строкой, что может оказать значительное влияние на память в случае, если строковое значение является единственной вещью в дереве, которая действительно представляет интерес.В этих случаях вы можете деактивировать родительские отношения с помощью ключевого аргумента smart_strings.

(я не знаю, является ли это проблемой в вашем случае, но это кандидат. Я был укушенэто сам один раз; -))

1 голос
/ 10 марта 2011

На http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks есть отличная статья, которая демонстрирует графическую отладку структур памяти; это может помочь вам выяснить, что не выпускается и почему.

Редактировать: Я нашел статью, из которой я получил эту ссылку - Утечки памяти Python

0 голосов
/ 23 ноября 2011

Кажется, проблема связана с библиотекой, на которую опирается lxml: libxml2, написанной на языке Си.Вот первый отчет: http://codespeak.net/pipermail/lxml-dev/2010-December/005784.html Эта ошибка не упоминалась ни в журналах исправлений ошибок lxml v2.3, ни в журналах изменений libxml2.

О, здесь есть последующие письма: https://bugs.launchpad.net/lxml/+bug/728924

Ну, я пытался воспроизвести проблему, но не получил ничего ненормального.Ребята, которые могут воспроизвести это, могут помочь прояснить проблему.

...