python:什么阻止垃圾收集
我正在尝试使用python:什么阻止垃圾收集,python,garbage-collection,Python,Garbage Collection,我正在尝试使用weakref.finalize根据 但是,Python的垃圾收集器从不收集对象,因此我无法测试我正在做什么weakref.finalize(请参见atexit) 但我不知道是什么阻碍了垃圾收集。 请参见以下示例: import gc from weakref import finalize, ref import objgraph def close_after_del(obj): def _cleaner(obj_): print("!obje
weakref.finalize
根据
但是,Python的垃圾收集器从不收集对象,因此我无法测试我正在做什么<仅当脚本完成时才会调用code>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\u referers
显示一个字典,它与globals
或locals
相关吗
根据@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!")
这里有两个问题。首先,在
finalize
调用中:
finalize(obj, _cleaner, obj)
回调和参数不应拥有对正在最终确定的对象的引用。由于您已直接将obj
作为回调参数之一,因此:
注意:必须确保func、args和kwargs不直接或间接拥有对obj的任何引用,否则obj将永远不会被垃圾收集。特别是,func不应该是obj的绑定方法
那么,您可能想知道应该如何访问该对象。答案是您不应该访问该对象。这个物体应该是死的
第二个问题是,在以下方面:
print(gc.get_referrers(w_fp) if w_fp is not None else "Weak reference is gone")
w_fp
是弱引用对象,而不是其引用对象。您应该使用w\u fp()
这里有两个问题。首先,在finalize
调用中:
finalize(obj, _cleaner, obj)
回调和参数不应拥有对正在最终确定的对象的引用。由于您已直接将obj
作为回调参数之一,因此:
注意:必须确保func、args和kwargs不直接或间接拥有对obj的任何引用,否则obj将永远不会被垃圾收集。特别是,func不应该是obj的绑定方法
那么,您可能想知道应该如何访问该对象。答案是您不应该访问该对象。这个物体应该是死的
第二个问题是,在以下方面:
print(gc.get_referrers(w_fp) if w_fp is not None else "Weak reference is gone")
w_fp
是弱引用对象,而不是其引用对象。您应该使用w\u fp()
w\u fp
是弱引用对象。它永远不会是None
。你是对的,我修复了它w\u fp
->w\u fp()
。不过,你仍然会得到弱引用的引用者。w\u fp
是一个弱引用对象。你是对的,我把它修好了w\u fp
->w\u fp()
。不过你仍然会得到弱引用的引用者。好的,我知道我需要在这里使用一些代理对象。好的,我知道我需要在这里使用一些代理对象。