我一直在使用IDLE中的Python对象,并观察到如果对象的成员变量发生了变化,则内存不会被释放!这是一个例子:
import weakref
import gc
class subclass():
def __init__(self, data):
self.data=data
def __repr__(self):
return self.data.__str__()
class newclass():
def __init__(self,data):
self.data=subclass(data)
def test(self):
refs=weakref.ref(self.data)()
self.data=None
gc.collect()
print ("ref", refs)
a = newclass(data=3)
a.test()
print ("val", a.data)
此代码的输出,我希望是:
ref None
val None
但事实证明,ref仍然是一个有效的引用,输出是:
ref 3
val None
我希望看到内存被释放。我想了解如何。
答案 0 :(得分:3)
不幸的是,你误解了一些至关重要的事情。当您调用从weakref
返回的weakref.ref
对象时,您将返回原始对象。尝试打印type(ref)
,看看如何返回<class '__main__.subclass'>
。请参阅docs on weakref.ref
:
如果指示对象仍然存在,则可以通过调用引用对象来检索原始对象;如果指示对象不再存在,则调用引用对象将导致返回
None
。
(强调我的)
你调用了引用对象并让你的类subclass
回来了;因此,对ref
的引用仍然存在,不允许它被垃圾收集。
如果你不打电话,另一方面,你会注意到行print('ref', refs)
如何表明引用已经死了:
ref <weakref at 0x7f3028188a48; dead>
val None
即作为对象的唯一参考,并且由于它很弱,它被收集了。
顺便说一句,如果你想在Python 2和3之间移植,你会希望你的类从object
继承而不是使用空括号()
。如果您不关心可移植性,则可以删除括号而不改变语义。 : - )