Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python lxml解析器消耗所有内存_Python_Memory Leaks_Lxml - Fatal编程技术网

Python lxml解析器消耗所有内存

Python lxml解析器消耗所有内存,python,memory-leaks,lxml,Python,Memory Leaks,Lxml,我正在用python编写一些spider,并使用lxml库解析html,使用gevent库解析异步。我发现经过一段时间的工作后,lxml解析器开始消耗高达8GB的内存(所有服务器内存)。但我只有100个异步线程,每个线程最多可以解析300kb的文档 我已经测试过了,发现这个问题是从lxml.html.fromstring开始的,但我无法重现这个问题 这一行代码中的问题: HTML = lxml.html.fromstring(htmltext) 也许有人知道它可能是什么,或者想办法解决这个问题

我正在用python编写一些spider,并使用lxml库解析html,使用gevent库解析异步。我发现经过一段时间的工作后,lxml解析器开始消耗高达8GB的内存(所有服务器内存)。但我只有100个异步线程,每个线程最多可以解析300kb的文档

我已经测试过了,发现这个问题是从lxml.html.fromstring开始的,但我无法重现这个问题

这一行代码中的问题:

HTML = lxml.html.fromstring(htmltext)
也许有人知道它可能是什么,或者想办法解决这个问题

谢谢你的帮助

附言

向上:

我为使用lxml解析器的进程设置了ulimit-sv500000和ulit-sm615000

现在过了一段时间,他们开始在错误日志中写入:

“异常MemoryError:'lxml.etree.\u BaseErrorLog.\u receive'中的MemoryError()已忽略”

我无法捕获此异常,所以它会递归地在日志中写入此消息,直到磁盘上有可用空间为止


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

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

在某些情况下,智能字符串行为是不可取的。例如,这意味着树将通过字符串保持活动状态,如果字符串值是树中唯一实际感兴趣的内容,那么字符串可能会对内存产生相当大的影响。对于这些情况,可以使用关键字参数smart\u strings停用父关系


(我不知道这是否是你的问题,但它是一个候选者。我自己也曾被它咬过一口;-)

有一篇优秀的文章演示了内存结构的图形调试;这可能会帮助您了解哪些内容没有发布,以及为什么没有发布


编辑:我找到了我从中获得该链接的文章-

问题似乎源于lxml所依赖的库:用C语言编写的libxml2。 以下是第一份报告: lxml v2.3错误修复日志或libxml2更改日志中都没有提到这个错误

哦,这里有后续邮件:


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

我不使用xpath。我在这行代码中遇到的问题HTML=fromstring(htmlcode)。因为当我测试这个bug时,我从脚本中删除了任何其他内容。也没有任何保留的引用。嗨,steven,我刚刚遇到lxml内存问题,我使用smart_strings=False解决我的问题,而不更改任何其他代码。但我好奇的是,为什么python垃圾收集器没有将内存收集回系统?我不再使用树。@young001:您可能仍然使用字符串,因为它们是“智能字符串”,所以它们仍然使用树(通过保留对其元素的引用…),这意味着只要您保留对此类“智能字符串”的引用,这将防止树被垃圾收集。我在函数中使用它,返回字符串,然后将其存储到数据库中,因此情况将类似于“仍然使用字符串”。应在函数结束时收集字符串。函数中没有全局变量。虽然这很奇怪-因为内存使用量没有增长,它只是在某个点上爆炸。你不能在具有4 GB内存的虚拟机中运行它吗?我可以创建一个监视进程,如果主进程启动内存,它将重新启动主进程。但这不是一个答案,因为错误仍然存在。你曾经修复过这个问题吗?我也遇到了同样的问题——非常令人沮丧!也许没有人发现这个bug的原因是它正常运行了大约10分钟,然后砰的一声,100%内存。我试图将这个问题发布给lxml的人,但他们拒绝了。更多细节请看这里:我试着复制了大约两周。但是什么都没有。这似乎是schroedinbug。只是澄清一下,这个bug-至少对我来说-不是RAM使用的增加(像正常的mem泄漏)。它运行得很好,完全正常,但突然,在十分钟后,比如说(可能是15-2000个对象),我的RAM完全被淹没,并将保持这样,直到进程被终止。因此,这不是一个“正常”(或至少是透明)的内存泄漏。仅供参考。
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)