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

Jackey Python 839 次浏览 没有评论
# 如何在环状数据结构中管理内存
from pip._vendor.distlib.compat import raw_input


class A(object):
    def __del__(self):
        print('in A.__del__')


a = A()

import sys

# 类的初始化会有一个引用
print(sys.getrefcount(a))

a2 = a
print(sys.getrefcount(a) - 1)

# 垃圾回收机制,当引用计数减为0的时候,系统自动回收

del a2

# 改变a的引用,系统会自动回收
a = 5

print(1111)


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

class Data(object):
    def __init__(self, value, owner):
        self.owner = 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

# 强制回收 也是不行的
# import gc
# gc.collect()

raw_input('wait...')

# 弱引用
b = A()
print(sys.getrefcount(b) - 1)

print('---------------')

import weakref

b_wref = weakref.ref(b)
b2 = b_wref()
print(sys.getrefcount(b) - 1)

# 此时可以回收
del b
del b2

print('-----------')

# 改造之后
import weakref


class Data1(object):
    def __init__(self, value, owner):
        # 更改为弱引用
        self.owner = weakref.ref(owner)
        self.value = value

    def __str__(self):
        return "%s's data1, value is %s" % (self.owner(), self.value)

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


class Node1(object):
    def __init__(self, value):
        self.data = Data1(value, self)

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


node1 = Node1(100)
# 此时可以正常回收
del node1

print('---------')

 

发表评论

您的电子邮箱地址不会被公开。

Go