我正在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()被忽略”。
我无法捕获此异常,因此它会在日志中递归写入此消息,因为磁盘上有可用空间。
如何捕获此异常以终止进程,以便守护进程可以创建新进程?
答案 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
好吧,我试图重现这个问题,但没有任何异常。能够重现它的人可能有助于澄清问题。