Python在更改类中对象的成员时释放内存
我一直在空闲状态下处理Python对象,并观察到如果对象的成员变量发生变化,内存不会被释放!以下是一个例子:Python在更改类中对象的成员时释放内存,python,python-3.x,class,Python,Python 3.x,Class,我一直在空闲状态下处理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,d
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
我希望看到内存被释放。我想知道是怎么回事。不幸的是,你误解了一些重要的事情。调用从
weakref.ref
返回的weakref
对象时,将返回原始对象。尝试打印类型(ref)
并查看如何返回
。见:
如果引用对象仍然处于活动状态,则可以通过调用引用对象来检索原始对象;如果引用对象不再处于活动状态,调用引用对象将导致返回None
(强调矿山)
您调用了引用对象,并获得了类子类
;因此,ref
中仍然存在对它的引用,不允许它被垃圾回收
另一方面,如果不调用它,您会注意到print('ref',refs)
行如何指示引用已失效:
ref <weakref at 0x7f3028188a48; dead>
val None
ref
瓦尔诺内
i、 e作为对对象的唯一引用,由于它很弱,所以被收集
另一方面,如果您想在Python 2和Python 3之间实现可移植性,您将希望您的类从
对象
中进行子类化,而不是使用空括号()
。如果您不关心可移植性,可以删除括号而不改变语义。:-) 不幸的是,你误解了一些重要的事情。调用从weakref.ref
返回的weakref
对象时,将返回原始对象。尝试打印类型(ref)
并查看如何返回
。见:
如果引用对象仍然处于活动状态,则可以通过调用引用对象来检索原始对象;如果引用对象不再处于活动状态,调用引用对象将导致返回None
(强调矿山)
您调用了引用对象,并获得了类子类
;因此,ref
中仍然存在对它的引用,不允许它被垃圾回收
另一方面,如果不调用它,您会注意到print('ref',refs)
行如何指示引用已失效:
ref <weakref at 0x7f3028188a48; dead>
val None
ref
瓦尔诺内
i、 e作为对对象的唯一引用,由于它很弱,所以被收集
另一方面,如果您想在Python 2和Python 3之间实现可移植性,您将希望您的类从
对象
中进行子类化,而不是使用空括号()
。如果您不关心可移植性,可以删除括号而不改变语义。:-) 在Python3中,从对象子类化是隐式的,但我认为这是一个很好的风格点,它有助于使您的代码易于移植到Python2。我们都知道,显式比隐式好:)@juanpa.arrivillaga我同意(尽管这实际上是由2ps编辑的:-)谢谢。明白了!在Python3中,从对象子类化是隐式的,但我认为这是一个很好的风格点,它有助于使您的代码易于移植到Python2。我们都知道,显式比隐式好:)@juanpa.arrivillaga我同意(尽管这实际上是由2ps编辑的:-)谢谢。明白了!