【问题标题】:How do I prevent memory leak when I load large pickle files in a for loop?在 for 循环中加载大型泡菜文件时如何防止内存泄漏?
【发布时间】:2013-04-23 17:26:21
【问题描述】:

我有 50 个 pickle 文件,每个文件大小为 0.5 GB。 每个 pickle 文件都包含一个自定义类对象列表。 我使用单独加载文件没有问题 以下函数:

def loadPickle(fp):
    with open(fp, 'rb') as fh:
        listOfObj = pickle.load(fh)
    return listOfObj

但是,当我尝试迭代加载文件时 我遇到了内存泄漏。

l = ['filepath1', 'filepath2', 'filepath3', 'filepath4']
for fp in l:
    x = loadPickle(fp)
    print( 'loaded {0}'.format(fp) )

在打印loaded filepath2 之前我的内存溢出。 如何编写代码来保证每次迭代期间只加载一个泡菜?

对 SO 相关问题的回答建议使用 weakref 模块中定义的对象或使用 gc 模块进行显式垃圾收集,但我很难理解如何将这些方法应用于我的特定用例。这是因为我对引用的工作原理了解不足。

相关:Python garbage collection

【问题讨论】:

  • 尝试在for fp in l:之后添加x = None
  • 嗨 Ionut Hulub,谢谢。成功了!
  • 这里没有实际的内存泄漏。只是旧的x值要等到新的值被赋值后才能释放,所以需要足够的内存才能同时在内存中存两个值。

标签: python memory-leaks python-3.x garbage-collection pickle


【解决方案1】:

您可以通过在for fp in l: 之后添加x = None 来解决此问题。

这样做的原因是因为它将取消引用变量x,从而允许python垃圾收集器在第二次调用loadPickle()之前释放一些虚拟内存。

【讨论】:

  • 这实际上并不能保证有效。一旦你停止引用它,Python 允许 处理它,但这不是必需 的。幸运的是,只要您在任何地方都没有任何循环引用,CPython 实现这样做,但是依赖于明确记录为不能保证的某些内容的代码至少应该与 cmets 一起提供和警告……
  • 确实如此。感谢您的添加@abarnert
  • del x不是更好吗?只是为了确保变量 x 将被取消引用。
  • 我不认为这有什么不同,但这是一个有效的选择。
  • 我遇到的情况是它不起作用 - 使用的内存仍在累积。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
相关资源
最近更新 更多