【问题标题】:python: what stops garbage collectionpython:什么停止垃圾收集
【发布时间】:2019-02-18 23:15:24
【问题描述】:

我正在尝试使用weakref.finalize根据https://docs.python.org/3.6/library/weakref.html#comparing-finalizers-with-del-methods处理对象的销毁

但是,Python 的垃圾收集器从不收集对象,所以我无法测试我在做什么。 weakref.finalize 仅在脚本完成时被调用(参见atexit)。

但我不知道是什么阻止了垃圾收集。 请参阅以下示例:

import gc

from weakref import finalize, ref

import objgraph


def close_after_del(obj):

    def _cleaner(obj_):
        print("!object get's closed now")
        obj_.close()

    finalize(obj, _cleaner, obj)


print('open file')
fp = open('blub', 'w')
close_after_del(fp)

print('check for other references:')
objgraph.show_refs(fp)
print(gc.get_referrers(fp))
print('delete and collect it')
w_fp = ref(fp)
del fp
gc.collect()
print('check references again:')
print(gc.get_referrers(w_fp) if w_fp() is not None else "Weak reference is gone")
print("should be deleted by now but isn't")

objgraph.show_refs(w_fp)

objgraph 只显示不重要的弱引用(我只是在之后添加它以检查引用)。 gc.get_referrers 显示字典,这与globalslocals 有关吗?


根据@user2357112的回答解决:

from weakref import finalize


def close_after_del(proxy, fp):

    def _cleaner():
        print("!object gets closed now!")
        fp.close()

    finalize(proxy, _cleaner)


class Proxy():

    def __init__(self, fp):
        self.fp = fp


print('open file')
proxy = Proxy(open('blub', 'w'))
close_after_del(proxy, proxy.fp)

print('delete and collect it')
del proxy
import gc; gc.collect()
print("Got collected!")

【问题讨论】:

  • w_fp 是一个弱引用对象。它永远不会是None
  • 你说得对,我修好了w_fp -> w_fp()
  • 不过,您仍然会获得弱引用的引荐来源网址。

标签: python garbage-collection


【解决方案1】:

这里有两个问题。首先,在finalize 调用中:

finalize(obj, _cleaner, obj)

回调和参数不应拥有对正在完成的对象的引用。由于您已将obj 直接设为回调参数之一,因此the object can't be collected

注意:确保 funcargskwargs 不拥有任何对obj,直接或间接,否则 obj 将永远不会被垃圾回收。特别是,func 不应该是 obj 的绑定方法。

那么,您可能想知道应该如何访问该对象。答案是您不应该访问该对象。该对象应该是死的。


第二个问题是在以下行中:

print(gc.get_referrers(w_fp) if w_fp is not None else "Weak reference is gone")

w_fp 是弱引用对象,而不是它的引用对象。你应该使用w_fp()

【讨论】:

  • 好的,我明白了,这里需要用到一些代理对象。
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
相关资源
最近更新 更多