Python内存管理

1.del与垃圾回收:del语句删除名称,而不是对象。仅当变量保存的是对象的最后一个引用,或者无法得到对象时,del命令才会导致对象被当作垃圾回收。

class A(list):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print("create", id(self))

    def __del__(self):
        print("del", id(self))

a = A([10, 20])
b = A([a, 30])
a[-1] = b
print(a, b)
del b
del a
print("exit...")
"""
create 2418962187912
create 2418962186632
[10, [[...], 30]] [[10, [...]], 30]
exit...
del 2418962187912
del 2418962186632
"""

a = A([10, 20])
b = A([a, 30])
a[-1] = b
print(a, b)
del b
del a[-1]
print("exit...")
"""
create 2153516090936
create 2153516089656
[10, [[...], 30]] [[10, [...]], 30]
del 2153516089656
exit...
del 2153516090936
"""

 

2.如果两个对象相互引用,当它们的引用只存在二者之间时,垃圾回收程序会判定它们都无法获取,因而将它们都销毁。

3.关于弱引用:不要直接使用 weakref.ref(obj) 创建对象,应使用 weakref.finalize(obj, func) 或 WeakValueDictionary,WeakKeyDictionary,WeakSet 代替。

 weakref.finalize(obj, func) 弱引用对象 obj,当obj被当作垃圾回收时, 调用函数 func。

    WeakValueDictionary经常用于缓存,它实现了一个可变映射,里面的值是对象的弱引用,当被引用的对象在程序中的其他地方被当作垃圾回收后,对应的键会自动从WeakValueDictionary中删除;

    WeakKeyDictionary 与之不同的地方在于,其键是弱引用,WeakKeyDictionary可以为应用中其他部分拥有的对象附加数据,这样就无需要为对象添加属性。

    WeakSet类保存元素的弱引用的集合类,元素没有强引用时,集合会把它删除。

    需要注意的是,不是每个类型的对象都能作为弱引用的目标,其中 int 与 tuple 及其子类都不可以, list 与 dict 实例不可以,但其子类可以。

import weakref

a = {1, 2, 3}
def bye():
    print("Byte! Cruel world!")
wref = weakref.finalize(a, bye)
print(wref.alive)
del a
print(wref.alive)
print("exit...")

#
True
Byte! Cruel world!
False
exit...

 

class Fruit():
    def __init__(self, kind):
        self.kind = kind
    def __repr__(self):
        return "Fruit(%r)" % self.kind

fruits = [Fruit("apple"), Fruit("banana"), Fruit("Peach")]
stock = weakref.WeakValueDictionary()

for fruit in fruits:
    stock[fruit.kind] = fruit

del fruits
del fruit

print(list(stock.keys())) # []
print(list(stock.values())) # []

 

class Fruit():
    def __init__(self, kind):
        self.kind = kind
    def __repr__(self):
        return "Fruit(%r)" % self.kind

fruits = [Fruit("apple"), Fruit("banana"), Fruit("Peach")]
stock = weakref.WeakKeyDictionary()
print(fruits)

for fruit in fruits:
    stock[fruit] = fruit.kind

del fruits
del fruit

print(list(stock.keys())) # []
print(list(stock.values())) # []

 

posted @ 2020-03-23 20:15  阿Hai  阅读(142)  评论(0)    收藏  举报