Python/lxml占用了太多内存

Python/lxml占用了太多内存,python,optimization,memory-leaks,lxml,Python,Optimization,Memory Leaks,Lxml,该程序非常简单,递归地下降到目录并提取元素。目录是1k,大约有200个0.5m的文件。 我看到它在一段时间后消耗了大约2.5g的内存,这是完全不可接受的,脚本并不是唯一一个吃掉所有东西的。我不明白为什么它不能释放记忆。显式del没有帮助。 有什么技术需要考虑? from lxml import etree import os res=set() for root, dirs, files in os.walk(basedir): for i in files: tre

该程序非常简单,递归地下降到目录并提取元素。目录是1k,大约有200个0.5m的文件。 我看到它在一段时间后消耗了大约2.5g的内存,这是完全不可接受的,脚本并不是唯一一个吃掉所有东西的。我不明白为什么它不能释放记忆。显式del没有帮助。 有什么技术需要考虑?


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

您保留了对树中元素的引用,即
\u elementunicodesult
。元素保留对其父元素的引用。这可以防止整个树被垃圾收集

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

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))

什么类型是
i
?你打算用
res
做什么?你是如何测量内存消耗的?
lxml.etree.\u ElementUnicodeResult
对象本身可能没有使用那么多内存,但是由于你可以对它们执行
.getparent()
操作,它们保留了对树的引用,这意味着Python不能对树进行垃圾收集。因此,在我看来,在将它们添加到集合之前将它们转换为字符串应该有助于垃圾收集器完成其工作。@Pooh:这是一种已知的、有文档记录的行为cf和链接的post.Great。内存优化很少有那么容易,很高兴它成功了;-)