【发布时间】: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