lxml解析器吃掉所有内存

时间:2011-03-10 13:29:58

标签: python memory-leaks lxml

我正在python中编写一些蜘蛛并使用lxml库来解析html和gevent库以进行异步。我发现在经过一段时间的工作之后,lxml解析器开始占用内存高达8GB(所有服务器内存)。但我只有100个异步线程,每个线程解析文件最大为300kb。

我测试并在lxml.html.fromstring中启动该问题,但我无法重现此问题。

这行代码中的问题:

HTML = lxml.html.fromstring(htmltext)

也许有人知道它可能是什么,或者锄头来解决这个问题?

感谢您的帮助。

P.S。

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:

我为使用lxml解析器的进程设置了ulimit -Sv 500000和uliit -Sm 615000。

现在有一段时间他们开始写错误日志:

“异常MemoryError:'lxml.etree._BaseErrorLog._receive'中的MemoryError()被忽略”。

我无法捕获此异常,因此它会在日志中递归写入此消息,因为磁盘上有可用空间。

如何捕获此异常以终止进程,以便守护进程可以创建新进程?

3 个答案:

答案 0 :(得分:7)

您可能会保留一些使文档保持活动的引用。例如,请注意来自xpath评估的字符串结果:默认情况下,它们是“智能”字符串,它提供对包含元素的访问,因此如果您保留对它们的引用,则将树保留在内存中。请参阅xpath return values上的文档:

  

在某些情况下,智能字符串行为是不合需要的。例如,这意味着树将由字符串保持活动,在字符串值是树中实际感兴趣的唯一事物的情况下,这可能具有相当大的内存影响。对于这些情况,您可以使用关键字参数smart_strings停用父母关系。

(我不知道你的情况是否存在这个问题,但它是候选人。我曾经被自己咬过一次; - )

答案 1 :(得分:1)

http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks上有一篇很好的文章,展示了内存结构的图形化调试;这可能有助于你弄清楚什么没有被释放以及为什么。

修改:我找到了我从中获得该链接的文章 - Python memory leaks

答案 2 :(得分:0)

似乎问题源于库lxml依赖于:libxml2,它是用C语言编写的。 这是第一份报告:http://codespeak.net/pipermail/lxml-dev/2010-December/005784.html 在lxml v2.3错误修复日志或libxml2更改日志中未提及此错误。

哦,这里有后续邮件:https://bugs.launchpad.net/lxml/+bug/728924

好吧,我试图重现这个问题,但没有任何异常。能够重现它的人可能有助于澄清问题。