def make_cycle():
l = [ ]
l.append(l)
make_cycle()
这个时候就需要垃圾回收机制(garbage collection),来回收循环应用的对象。
import gc
print "Garbage collection thresholds: %r" % gc.get_threshold()
# Garbage collection thresholds: (700, 10, 10)
当内存溢出时,不会自动调用garbage collection( gc ),
import sys, gc
def make_cycle():
l = {}
l[0] = l
def main():
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)
print "Creating cycles..."
for i in range(10):
make_cycle()
collected = gc.collect()
print "Garbage collector: collected %d objects." % (collected)
if __name__ == "__main__":
ret = main()
sys.exit(ret)
调用gc的策略有两种,一种是固定时间间隔进行调用,另一种是基于事件的调用。
import gc
class A(object):
def __del__(self):
print '__del__ in A'
class B(object):
def __del__(self):
print '__del__ in B'
class C(object):
pass
if __name__=='__main__':
print 'collect: ',gc.collect()
print 'garbage: ',gc.garbage
a = A()
b = B()
c = C()
a.cc = c
c.bb = b
b.aa = a
del a,b,c
print 'collect: ',gc.collect()
print 'garbage: ',gc.garbage
del gc.garbage[0].cc # 当然,这是在我们知道第一个对象是 a的情况下,手动破除引用循环中的环
del gc.garbage[:] # 消除garbage对a和b对象的引用,这样引用计数减1等于0,就能回收a、b、c三个对象了
print 'garbage: ',gc.garbage
print '----------------------------'
print 'collect: ',gc.collect()
print 'garbage: ',gc.garbage
如上所示:调用一次gc.collect(),首先检查因为引用循环而不可达对象,
import weakref
class Foo(object):
pass
a = Foo()
a.bar = 123
a.bar2 = 123
del a
del a.bar2
b = weakref.ref(a)
print b().bar
print a == b()
c = weakref.proxy(a)
print c.bar
print c == a
del:只是使变量所代表的对象的引用计数减1,并在对应空间中删除该变量名。
闭包空间的变量和自由变量的释放问题:
class A(object):
def __init__(self,name):
self._name = name
def __del__(self):
print '__del__ in ',self._name
def f1():
a = A('a')
b = A('b')
def f2():
c = A('c')
print a
return f2
if __name__=='__main__':
print 'f2 = f1():'
f2 = f1()
print '\na.__closure__:'
print f2.__closure__ # 查看f2的闭包里面引用了a对象
print '\na():'
f2()
print '\ndel f2:'
del f2 # 此时已经没有任何变量可以引用到返回的f2对象了。
print '\nover!'
注:python2.7版本