【问题标题】:Deleted objects still referenced in pickle仍然在pickle中引用的已删除对象
【发布时间】:2023-03-31 05:20:01
【问题描述】:

在我的项目中,我定期使用酸洗来表示进程的内部状态以实现持久性。作为正常操作的一部分,对对象的引用被添加到多个其他对象中或从多个其他对象中删除。

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

如果卖家将其财产从市场上撤下或出售,则地址将从两个列表中删除。

Persons 和 RealEstateAgents 都是用于酸洗的中心对象(Masterlist)列表的成员。我的问题是,当我添加和删除属性并随着时间的推移反复腌制 Masterlist 对象时,腌制文件的大小会增长,即使我删除(实际上是删除)比我添加的更多的属性。我意识到,在酸洗 Masterlist 中,有一个循环引用。我的应用中有很多循环引用。

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

虽然应用程序在酸洗/取消酸洗之前和之后都能正常运行,但不断增长的文件大小是一个问题,因为该进程需要长时间运行,并且不能重新初始化它。

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

非常感谢

【问题讨论】:

  • 我最终使用了 objgraph 和 heapy 来找到泄漏的来源 - 非常感谢。哦,一旦加载到内存中,引用实际上仍在对象中,只是不在我预期的位置。这是处理复杂对象关系的好工具!

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


【解决方案1】:

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

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

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

此外,某些腌制对象会(沿着腌制链)腌制全局,并且通常是腌制对象内循环引用的原因。

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

【讨论】:

  • 非常酷的模块。花了一些时间探索我的代码生成的类似意大利面条的图形:) 但是,我在内存中找不到任何地址类型对象的引用。使用: objgraph.by_type('Address') 即使它们似乎在泡菜文件中。您提到使用 objgraph 直接探索泡菜,有什么指示吗?
  • 我没有说它可以直接探索pickle,但它是我调试pickle时使用的好工具。请参阅上面的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多