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

时间:2014-09-03 19:27:36

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

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

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

如果卖方将其财产从市场上撤下或出售,则该地址将从两个清单中删除。

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

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

虽然应用程序在pickle / unpickling之前和之后正确运行,但是增长的文件大小是一个问题,因为该过程意味着长时间运行,并且重新初始化它不是一种选择。

我的例子是名义上的,这可能是一个问题,但我想知道是否有人有使用泡菜的垃圾收集问题的经验,当他们包含循环引用或任何其他可能指向我的调试这个的正确方向。也许一些有用的工具。

非常感谢

1 个答案:

答案 0 :(得分:2)

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

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

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

此外,某些酸洗物体(在泡菜链下方)泡菜全球,并且通常是腌制物体内圆形参考的原因。

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