【问题标题】:How to make python ignore an object for garbage collection?如何让python忽略垃圾收集的对象?
【发布时间】:2019-10-03 18:43:13
【问题描述】:

在我的代码开始时,我加载了一个巨大的 (33GB) 腌制对象。这个对象本质上是一个包含许多相互连接的节点的巨大图。

我定期运行 gc.collect()。当我加载了巨大的对象时,这需要 100 秒。当我将代码更改为不加载大对象时, gc.collect() 需要 0.5 秒。我假设这是由于 python 在每次调用 gc.collect() 时检查该对象的每个子对象的引用循环引起的。

我知道,无论是巨大的对象,还是它在开始加载时引用的任何对象,都不需要进行垃圾回收。我如何告诉python这个,这样我就可以避免100s gc时间?

【问题讨论】:

  • 也许看看gc.is_tracked(large_object)
  • 为什么要手动调用gc.collect
  • 如果可能,不要使用 pickle 来序列化 30gb 的数据集。如此大的数据通常具有更专业的表示。你处理什么数据?

标签: python garbage-collection


【解决方案1】:

在 python 3.7 中,您可能可以使用 https://docs.python.org/3/library/gc.html#gc.freeze 破解某些东西

allocate_a_lot()
gc.freeze() # move all objects to a permanent generation. none will be collected
allocate_some_more()
gc.collect() # collect all non-frozen objects
gc.unfreeze() # return to sanity

这就是说,我认为 python 没有提供你想要的工具。一般来说,所有垃圾收集语言都不希望您进行手动内存管理。

【讨论】:

  • 非常感谢您的回答。但是,如果没有对它的引用,它是否会阻止对象被垃圾收集,它不会将 gc 时间减少到未加载对象时的位置。很抱歉删除了“选择的答案”,我不应该在尝试解决方案之前把它放在那里。
  • 删除接受没有问题。您可以对代码进行 C 级配置文件吗?我发现它怀疑 gc 即使有巨大的堆也需要 100 秒。类似于 linux perf 工具。
  • 您也可以尝试在 gc.set_threshold 中设置更大的限制。或者在极端情况下使用 gc.disable 完全禁用循环垃圾收集器。 refcounting gc 仍然存在。
  • 归根结底,当我删除 gc.collect() 调用时,我的代码最终可以正常工作。这并不能解决我最初提出的问题,但这意味着我不再需要解决该问题。
猜你喜欢
  • 1970-01-01
  • 2014-05-03
  • 2010-11-08
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
相关资源
最近更新 更多