2009-07-14 89 views
3

gc.get_referrers(obj)应该可以为对象返回一个空列表,但该对象仍然可以通过弱引用访问?Python对象没有引用,但仍然可以通过weakref访问吗?

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

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

编辑:已解决。我发现这个变量有一个很强的参考 - 它在游戏事件循环中,但不是一个类变量,所以get_referrers没有选择它。

+0

请举一个简单的代码示例。否则不清楚你的意思。是弱引用本身可访问还是被引用的对象本身可以通过weakref访问? – yairchu 2009-07-14 20:35:51

+0

你是如何找到参考变量的?我试图追踪这样一个泄漏,但它是间歇性的,gc.get_referrers返回[]。有没有办法找到对象的“本地”引用? – papercrane 2013-04-04 20:43:16

回答

1

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

弱引用将不被保留对象活着。

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

是什么让你觉得对象没有被收集?另外,你有没有尝试过gc.collect()?

+0

当我期望一个None时,我仍然通过weakref得到一个对象实例。 – 2009-07-14 20:35:31

0

由于Christopher says,弱引用不计入对象引用计数,因此无法防止Python删除对象。

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

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可能就是您所需要的。

1

也可能是一个引用被一个错误的C扩展泄露,恕我直言,你不会看到引用者,但引用计数仍然没有下降到0.你可能想要检查返回值sys.getrefcount

1

我很高兴你发现你的问题,与最初的问题无关。尽管如此,如果其他人有这个问题,我对后代的回答有不同的看法。

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

来自Python 2。7手册:“一个实现可以推迟垃圾收集或完全忽略它 - 只要没有收集到仍然可以访问的对象,垃圾收集的实现质量就是一个实施质量问题。”

非OP垃圾收集器是合法的。

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

相关问题