python - 在覆盖该引用之前删除对大型 Python 对象的引用有什么好处吗?
问题描述
我正在运行一些对数据库中的文档进行迭代的大量内存脚本,并且由于服务器上的内存限制,我在每次迭代结束时手动删除了对大对象的引用:
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 系统上,查看resident set size。你也可以使用sys._debugmallocstats()
.
除非您看到驻留集大小不断增长,否则我不会担心。
推荐阅读
- ruby-on-rails - Rails 未定义的局部变量或方法“first”用于 ActiveRecord::NullMutationTracker:Class on local
- linux - 在 supervisord 启动的进程之间共享值
- reactjs - 谷歌地图反应多边形问题
- asp.net-mvc - [ASP.NET-MVC]如何在同一个控制器中创建和编辑数据
- node.js - 如何在 Nginx Docker 映像上使用 Traefik PathPrefix?
- javascript - 带有 svg 图像、css、html、js 的页面之间的过渡效果
- mysql - SQL 透视查询以在单行中获取结果
- node.js - 为什么 npm 会在本地安装包?
- go - 是否可以通过关闭 src 来中断 io.Copy?
- python - 在 Python 上打印字符串的所有其他字母而没有空格