【问题标题】:Memory leak when using pickle in python在 python 中使用 pickle 时的内存泄漏
【发布时间】:2016-03-16 09:03:26
【问题描述】:

我有一个很大的 pickle 文件,其中包含数百个用 python 训练的 r 模型:这些是使用库 rpy2 构建的统计模型。

我有一个类,每次调用其中一个方法时都会加载pickle文件(此方法在循环中被调用多次)。 即使没有指向加载内容的引用,加载 pickle 文件内容所需的内存(大约 100 MB)也不会被释放。我正确打开和关闭输入文件。我还尝试在每次迭代时重新加载 pickle 模块(甚至 rpy)。没有什么变化。似乎只是加载内容的事实会永久锁定一些内存。

【问题讨论】:

  • 我已经读过了。我的情况不同。在这种情况下,会有一个指向加载内容的引用。我做了类似的事情:with open(trained_models_file, 'r') as file_: pickle.load(file_) 当方法调用完成时应该释放内存
  • 我不认为 GC 不能保证在任何特定点被调用,即使资源是空闲的。
  • 当然不能保证。但它应该在内存泄漏和连续的程序终止发生之前被明确地调用。无论如何,我对代码进行了内存分析,发现调用了 GC,导致程序使用的其他内存的一部分被释放。但不是链接到pickle加载此文件的内存。
  • 如果你编写一个脚本,只在无限循环中加载泡菜,每一步都休眠一段时间,你是否观察到泄漏?

标签: python pickle rpy2


【解决方案1】:

我可以重现该问题,现在这是 rpy2 问题跟踪器中的一个未解决问题:https://bitbucket.org/rpy2/rpy2/issues/321/memory-leak-when-unpickling-r-objects

编辑:问题已解决,修复包含在 rpy2-2.7.5(刚刚发布)中。

【讨论】:

  • 太棒了!问题是什么?问题是什么?什么时候发布调试版?
  • 从 pickle 中提取的 R 对象未正确释放(在 rpy2 的 C 代码中)。 rpy2 2.7.5 现已发布并在 pypi 上。
【解决方案2】:

如果您遵循此建议,请暂时这样做,因为我不能 100% 确定此解决方案,但如果可以的话,我想尽力帮助您。

在 Python 中,垃圾回收不再使用 引用计数,即当 Python 检测到有多少对象正在引用一个对象时,当对象不再引用它时将其从内存中删除。

相反,Python 使用计划的垃圾回收。这意味着 Python 会设置一个垃圾收集时间,而不是立即进行。 Python 切换到这个系统是因为计算引用会减慢程序的速度(尤其是在不需要时)

对于您的程序,即使您不再指向某些对象,Python 可能还没有将其从内存中释放出来,因此您可以使用以下方法手动执行此操作:

gc.enable() # enable manual garbage collection
gc.collect() # check for garbage collection

如果您想了解更多信息,here 是 Python 垃圾收集文档的链接。我希望这对 Marco 有所帮助!

【讨论】:

  • 感谢您的建议。不过,已经尝试过了,但没有任何效果。
  • 引用计数在 CPython 中仍然被大量使用。您将在您正在使用的文档页面的开头找到以下内容:“收集器补充了 Python 中已经使用的引用计数”。除此之外,gc.enable() 不启用手动垃圾回收,而是启用 自动 垃圾回收,并且绝对不需要运行 gc.collect()
猜你喜欢
  • 2016-06-11
  • 2021-05-12
  • 2020-05-13
  • 2010-11-17
  • 2021-07-02
  • 1970-01-01
  • 2012-12-02
  • 2011-12-13
  • 2014-02-26
相关资源
最近更新 更多