Python对象没有引用但仍可通过weakref访问?

时间:2009-07-14 20:29:35

标签: python garbage-collection cpython

gc.get_referrers(obj)是否可以为对象返回一个空列表,但仍然可以通过弱引用访问该对象?

如果是这样,我将如何开始尝试确定此对象未被垃圾回收的原因?

编辑:我不确定代码示例在这种情况下究竟是如何帮助的 - 显然在某处有一个强大的引用,但如果我能找到它,我会被诅咒。我的印象是,对象的所有强引用都将由get_referrers()识别。

修改:已解决。我发现变量有一个强引用 - 它在游戏事件循环中,但不是一个类变量,所以get_referrers没有把它拿起来。

5 个答案:

答案 0 :(得分:1)

是:http://docs.python.org/library/weakref.html

弱引用不会保持对象存活。

get_referrers()函数只会找到那些支持垃圾收集的容器;将找不到引用其他对象但不支持垃圾收集的扩展类型。

是什么让你认为对象没有被收集?另外,你试过gc.collect()吗?

答案 1 :(得分:1)

也可能是某个引用被一个有缺陷的C扩展泄露,恕我直言,你将看不到引用,但仍然不会将引用数降为0.你可能想检查{{的返回值1}}。

答案 2 :(得分:1)

我很高兴你找到了你的问题,与最初的问题无关。尽管如此,我对后代的答案有不同看法,以防其他人遇到问题。

对象没有引用并且不被垃圾收集是合法的。

从Python 2.7手册:“允许实现推迟垃圾收集或完全省略它 - 实现垃圾收集的实现质量问题,只要没有收集到仍然可以访问的对象。” / p>

NO-OP垃圾收集器是合法的。

关于代数和引用计数垃圾收集器的讨论是指特定的CPython实现(在问题中标记)

答案 3 :(得分:0)

作为Christopher says,弱引用不计入对象引用计数,因此无法阻止Python删除对象。

但是,Python的垃圾收集器不会删除循环引用中的对象并定义了__del__方法。
您可以使用gc.garbage检查(并修复)此类情况。

答案 4 :(得分:0)

如果你有对该对象的强引用,请使用gc.get_referrers(obj)来查找它。

如果你有泄漏并且不知道泄漏的是什么,这可能会有所帮助:

http://mg.pov.lt/objgraph.py http://mg.pov.lt/blog/hunting-python-memleaks http://mg.pov.lt/blog/python-object-graphs.html

这是检查模块周围的薄包装;如果您有难以跟踪的不需要的引用,它可以帮助很多。但是,仅仅追踪一个参考,gc.get_referrers可能就是你所需要的。