7-7 如何在环状数据结构中管理内存

一、获取一个对象的引用数

>>> import sys
>>> help(sys.getrefcount)
Help on built-in function getrefcount in module sys:

getrefcount(...)
    getrefcount(object) -> integer
    
    Return the reference count of object.  The count returned is generally
    one higher than you might expect, because it includes the (temporary)
    reference as an argument to getrefcount().
help(sys.getrefcount)

返回的数总比期望的多了一个,因为这个数包含了一个传入到getrefcount()的参数。

>>> class A(object):
    def __del__(self):        #析构函数,在垃圾回收器回收变量时会调用析构函数
        print('in __del__')

例一:

>>> a = A()
>>> sys.getrefcount(a)
2

>>> a2 =a            #将a赋给a2  a的引用计数加1
>>> sys.getrefcount(a)
3
>>> del a2            #删除a2时,a的引用计数减1
>>> sys.getrefcount(a)
2
>>> a = 5            #将a赋值 时,a的引用计数再减1,就不再使用了,此时垃圾回收器将回收这个变量。
in __del__
>>> sys.getrefcount(a)        #再次获取引用计数时
101

例二:

>>> a = A()
>>> sys.getrefcount(a)
2
>>> a = 6
in __del__
>>> sys.getrefcount(a)
78
>>> 

例三:

>>> a = A()
>>> sys.getrefcount(a)
2
>>> a3 = a
>>> sys.getrefcount(a)
3
>>> a = 6
>>> sys.getrefcount(a)        #此时虽然引用计数变了,但是并未调用析构函数,说明,a3此时起了作用。
78
>>> 

二、弱引用:

1、Weakref,可以创建能访问对象但不增加引用计数的对象。当这个对象存在时返回这个对象的引用,当这个对象不存在时返回None

>>> a = A()
>>> import weakref
>>> sys.getrefcount(a)
2
>>> a_wref = weakref.ref(a)   #创建a的弱引用对象
>>> sys.getrefcount(a)        #此时引用计数不变
2
>>> a2 = a_wref()             #将弱引用对象赋给a2
>>> sys.getrefcount(a)        #此时的引用计数增加了
3
>>> a2 is a
True
>>> sys.getrefcount(a2)
3
>>> sys.getrefcount(a)
3
>>> sys.getrefcount(a)
3
>>> del a2
>>> del a
in __del__
>>> a_wref() is None       #此时弱引用对象已回收,返回None
True

2、键表的节点和数据:

class Data(object):
    def __init__(self,value,node): #定义数据的值,和属于的结点
        self.node = node
        self.value = value

    def __str__(self):
        return "%s 's data,value is %s" %(self.node,self.value)

    def __del__(self):
        print('in Data.__del__')

class Node(object):
    def __init__(self,value):   #定义一个结点,并赋初值数据。
        self.data = Data(value,self) #结点的数据是Data()类的对象,

    def __del__(self):
        print 'in Node.__del__'


node = Node(100)

del node
print ('end')

输出结果:

End

说明垃圾回收器并没有回收这个变量,因为他的引用计数不为0

3、使用弱引用改写:

import weakref
class Data(object):
    def __init__(self,value,node):
        self.node = weakref.ref(node)  #创建结果的弱引用对象
        self.value = value

    def __str__(self):
        return "%s 's data,value is %s" %(self.node(),self.value)

    def __del__(self):
        print('in Data.__del__')

class Node(object):
    def __init__(self,value):
        self.data = Data(value,self)

    def __del__(self):
        print 'in Node.__del__'


node = Node(100)

del node
print ('end')

输出结果:

in Node.__del__
in Data.__del__
end

说明:使用弱引用后,垃圾回收器可以回收变量了

猜你喜欢

转载自www.cnblogs.com/smulngy/p/9008545.html
7-7