Python/lxml占用内存过多

3

这个程序非常简单,递归地进入目录并提取一个元素。这些目录大约有1k大小,包含约200个0.5m的文件。 我发现它在一段时间后会消耗约2.5g的内存,这完全不能接受,脚本不是唯一的内存消耗者。我无法理解为什么它不释放内存。显式的删除操作也没有帮助。 有哪些技术需要考虑?


from lxml import etree
import os

res=set()
for root, dirs, files in os.walk(basedir):
    for i in files:
        tree = etree.parse(os.path.join(root,i), parser)
        for i in tree.xpath("//a[@class='ctitle']/@href"):
            res.add(i)
        del tree

1
i是什么类型的?你打算如何处理res - undefined
1
你是如何衡量内存消耗的? - undefined
3
lxml.etree._ElementUnicodeResult 对象本身可能不占用太多内存,但由于您可以对它们执行 .getparent() 操作,它们会保留对树的引用,这意味着 Python 无法对树进行垃圾回收。因此,从我的观察来看,在将它们添加到集合之前将它们转换为字符串应该有助于垃圾收集器完成其工作。 - undefined
1
@Pooh:这是一个已知且有文档记录的行为,参考链接:http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm 和相关帖子。 - undefined
1
@PeterWood 不用担心,我也猜到了。一切都好的;-) - undefined
显示剩余14条评论
1个回答

4

您正在保留来自树中一个名为_ElementUnicodeResult的元素的引用。该元素保留对其父级的引用。这会防止整个树被垃圾回收。

尝试将该元素转换为字符串并存储:

from lxml import etree
import os

titles = set()
for root, dirs, files in os.walk(basedir):
    for filename in files:
        tree = etree.parse(os.path.join(root, filename), parser)
        for title in tree.xpath("//a[@class='ctitle']/@href"):
            titles.add(str(title))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接