python - 已删除的对象仍在 pickle 中引用

标签 python garbage-collection pickle circular-reference resource-leak

在我的项目中,我定期使用 pickling 来表示持久化过程的内部状态。作为正常操作的一部分,对对象的引用会添加到多个其他对象中或从多个其他对象中删除。

例如,Person 可能有一个名为 address_list(列表)的属性,其中包含表示他们试图出售的所有属性的 Address 对象。另一个对象 RealEstateAgent 可能有一个名为 ports_for_sale 的属性(也是一个列表),其中包含相同类型的 Address 对象,但仅限于在其代理处列出的那些对象。

如果卖家将其属性(property)撤出市场或被出售,则该地址将从两个列表中删除。

Person 和 RealEstateAgents 都是用于 pickle 的中央对象(主列表)列表的成员。我的问题是,随着时间的推移,当我添加和删除属性并反复 pickle Masterlist 对象时, pickle 文件的大小会增加,即使我删除(实际上删除)的属性多于添加的属性。我意识到,在 pickling Masterlist 中,存在循环引用。我的应用程序中有很多循环引用。

我使用 pickletools.dis() 检查了 pickle 文件,虽然人类很难阅读,但我看到对已删除地址的引用。我确信它们已被删除,因为即使在 unpickle 之后,它们也不存在于各自的列表中。

虽然应用程序在 pickling/unpickling 之前和之后都可以正常运行,但不断增长的文件大小是一个问题,因为该过程需要长时间运行,并且无法重新初始化它。

我的例子是概念性的,问起来可能有些牵强,但我想知道是否有人有使用pickles处理垃圾收集问题的经验,当它们包含循环引用或其他任何可能为我指明正确方向的东西时来调试这个。也许一些工具会有帮助。

非常感谢

最佳答案

您可能想尝试objgraph...它可以极大地帮助您跟踪内存泄漏以及对象之间的循环引用和指针关系。

http://mg.pov.lt/objgraph/

我在调试 pickles 时使用它(在我自己的 pickling 包中,称为 dill)。

此外,某些 pickle 对象将(在 pickle 链中)pickle 全局变量,并且通常是 pickle 对象内循环引用的原因。

我在 dill 中还有一套 pickle 调试工具。请参阅 https://github.com/uqfoundation 处的 dill.detect ,其中有多种方法可用于诊断您要绑定(bind)到 pickle 的对象。例如,如果您设置 dill.detect.trace(True),它将在转储对象时打印出对 pickle 对象的所有内部调用。

关于python - 已删除的对象仍在 pickle 中引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25652244/

相关文章:

python - 如何处理同一张图上多个对象监听motion_notify_event

python - 包装器的 Gensim 模块属性错误

.net - 在抛出 OutOfMemoryException 之前调用 GC.Collect

java - 分析每个类的垃圾收集对象实例数

python - 为什么加载 pickle 对象比加载文件花费的时间长得多?

javascript - 是否可以为我的 sqlite 数据库生成一个随机且唯一的 5 位数 ID?

python - 如何优雅地将 Sklearn GridsearchCV 最佳参数传递给另一个模型?

Ruby WeakRef 具有隐式竞争条件?

python - 减少此 Pandas 代码读取 JSON 文件和 pickling 的内存使用

python - 我们可以从外部 URL 加载 .pkl 文件吗?