zoukankan      html  css  js  c++  java
  • 如何在环状数据结构中管理内存?

    需求:
    在python中,垃圾回收器通过引用计数来回收垃圾对象,但某些环状数据结构(树,图。。),存在对象间循环引用,比如树的父节点引用子节点,子节点也同时引用父节点。此时同时del掉引用父子节点,两个对象不能被立即回收。
    如何解决此类的内存管理问题?

    思路:
    使用标准库weakref,它可以创建一种能访问对象但是不增加引用计数的对象

    代码:

    import weakref
    
    # 下面构造两个类,他们互相引用
    class Data(object):
        
        def __init__(self,value,owner):
            self.owner = weakref.ref(owner)  # 使用弱引用的方法,不增加计数
            self.value = value
    
        def __str__(self):
            return "%s's data,value is %s" % (self.owner(),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        # 可以看到对象都被回收掉了
    input('wait....')
    
    ======================================================
    
    >>> class B():
    ...     def __del__(self):
    ...         print('in __del__')
    ... 
    >>> b = B()
    >>> b2 = weakref.ref(b)
    >>> b3 = b2()
    >>> b3 is b
    True
    >>> del b
    >>> del b3
    in __del__
    >>> b2() is None
    True
    >>> b = B()
    >>> b2 = weakref.ref(b)
    >>> b2()
    <__main__.B object at 0x7f74c52fa080>
    >>> b()
    Traceback (most recent call last):
      File "<ipython-input-60-3bf86fc5afda>", line 1, in <module>
        b()
    TypeError: 'B' object is not callable
    
    >>> b2
    <weakref at 0x7f74c53d4138; to 'B' at 0x7f74c52fa080>
    >>> B
    <class '__main__.B'>
    >>> b
    <__main__.B object at 0x7f74c52fa080>
    >>> 
    =================================================
    import weakref
    
    class Node:
        def __init__(self,data):
            self.data = data
            self._left = None
            self.right = None
    
        def add_right(self,node):
            self.right = node
            node._left = weakref.ref(self) # 这里实现弱引用来解决内存释放的问题
    
        @property
        def left(self):
            return self._left() # 这里的括号是关键,通过括号的调用,返回引用对象的本身,而不是弱引用,从而达到左右对称
    
        def __str__(self):
            return 'Node:<%s>' % self.data
    
        def __del__(self):
            print('in __del__; delete %s' % self)
    
    def create_linklist(n):
        head = Current = Node(1)
        for i in range(2,n+1):
            node  = Node(i)
            Current.add_right(node)
            Current = node
        return head
    
    head = create_linklist(1000)
    print(head.right,head.right.left)
    input()
    head = None
    
    # 模拟函数运行
    import time
    for _ in range(1000):
        time.sleep(1)
        print('run...')
    input('wait...')
    
    
  • 相关阅读:
    bash特性
    FHS 层级文件系统
    环境变量的问题
    linux认识
    搜索引擎的使用
    nginx
    部署操作手册
    git
    添加tag
    pycharm中使用git
  • 原文地址:https://www.cnblogs.com/Richardo-M-Q/p/13388450.html
Copyright © 2011-2022 走看看