【问题标题】:Python MemoryError - how can I force object deletionPython MemoryError - 我如何强制删除对象
【发布时间】:2010-10-28 22:49:48
【问题描述】:

我有一个处理多个文件的程序,并为每个文件生成一个报告。报告生成部分是一个单独的函数,它接受一个文件名,然后返回。在报告生成期间,中间部分缓存在内存中,因为它们可能用于报告的多个部分,以避免重新计算。

当我在一个目录中的所有文件上运行这个程序时,它会运行一段时间,然后崩溃并出现 MemoryError。如果我然后在同一目录上重新运行它,它将跳过它成功为其创建报​​告的所有文件,并继续。它会在再次崩溃之前处理几个文件。

现在,为什么在生成报告的方法调用之后没有清除所有资源,或者至少标记为垃圾回收?没有实例离开,我没有使用任何全局对象,每次文件处理后,所有打开的文件都会关闭。

我有什么方法可以验证没有对对象的额外引用?有没有办法在 Python 中强制进行垃圾回收?

关于实现和缓存的更多细节。每个报告中都有几个元素,然后每个元素可以依赖于不同的计算,每个计算可以依赖于其他计算。如果一个计算已经完成,我不想再做一次(其中大部分都很昂贵)。

这是缓存中的缩写版本:

class MathCache:
    def __init__(self): self.cache = {}
    def get(data_provider):
        if not data_provider.id in self.cache:
            self.cache[data_provider.id] = data_provider.get_value(self)
        return self.cache[data_provider.id]

创建它的一个实例,然后将其传递给报表中的每个元素。此实例仅保存在报表创建方法中的本地引用中。

所有 data_providers 都继承自一个公共类,该类用于根据构造函数参数和类名的散列生成实例的唯一 ID。我传递了 MathCache,因为 data_provider 本身可能依赖于其他计算。

【问题讨论】:

  • 更多代码会有所帮助。 “中间部分缓存在内存中”是模糊的——很可能是你的问题的原因。 Python 具有出色的垃圾收集功能。你以某种方式阻止了这种情况。
  • 您确定示例的第 4 行和第 5 行是正确的吗?那应该抛出一个 KeyError。
  • 我猜你的意思是 self.cache[data_provide.id] = get_value(self) 而不是 ".get_value(self)",对吧?
  • 对不起,是的。打字有点快,因为它不是从我的项目中剪切和粘贴代码。
  • 如果这是唯一的代码,那么删除 MathCache 应该会删除所有的引用。错误必须在其他地方。

标签: python memory resources garbage-collection


【解决方案1】:

您应该查看 gc 模块:http://docs.python.org/library/gc.html#module-gc

【讨论】:

    猜你喜欢
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2023-03-16
    • 2023-03-29
    • 2019-04-15
    相关资源
    最近更新 更多