在覆盖该引用之前删除对大型 Python 对象的引用有什么好处吗?

Is there any benefit to deleting a reference to a large Python object before overwriting that reference?

我是 运行 一些内存密集型脚本,它遍历数据库中的文档,由于服务器上的内存限制,我在每次迭代结束时手动删除对大对象的引用:

for document in database:
    initial_function_calls()

    big_object = memory_heavy_operation(document)
    save_to_file(big_object)

    del big_object

    additional_function_calls()

initial_function_calls()additional_function_calls() 都略显占用内存。通过显式删除对用于垃圾收集的大对象的引用,我是否看到任何好处?或者,在下一次迭代中保留它并让它指向一个新对象就足够了吗?

在这些情况下很常见;这取决于。 :-/

我假设我们在这里谈论的是 CPython。

使用del 或重新分配名称会减少对象的引用计数。只有当该引用可以达到 0 时,它才能被取消分配。因此,如果您无意中将对 big_object 的引用隐藏在某个地方,使用 del 将无济于事。

何时触发垃圾收集取决于分配和取消分配的数量。请参阅 gc.set_threshold() 的文档。

如果您非常确定没有进一步的引用,您可以使用 gc.collect()强制 垃圾收集 运行。如果您的代码不进行大量其他分配,这可能会有所帮助。

要记住的一件事是,如果 big_object 是由 C 扩展模块(例如 numpy)创建的,它可以管理自己的内存。在那种情况下,垃圾收集不会影响它!小整数和小字符串也是预先分配的,不会被垃圾收集。您可以使用 gc.is_tracked() 检查对象是否由垃圾收集器管理。

我建议您 运行 您的程序使用和不使用 del+gc.collect(),并监控使用的 RAM 量。在类 UNIX 系统上,查看 驻留集大小 。您也可以使用 sys._debugmallocstats().

除非你看到驻留集的大小越来越大,否则我不会担心。