第二章:数据结构-weakref:对象的非永久引用-缓存对象

2.8.5 缓存对象
ref和proxy类被认为是“底层”的。尽管它们对于维护单个对象的弱引用很有用,并且还支持对循环引用的垃圾回收,但WeakKeyDictionary和WeakValueDictionary类为创建多个对象的缓存提供了一个更适合的API.
WeakValueDictionary类使用它包含的值的弱引用,当其他代码不再真正使用这些值时,则允许垃圾回收。利用垃圾回收器的显示调用,下面展示了使用常规字典和WeakValueDictionary完成内存处理的区别:

import gc   # gc模块是解释器垃圾回收器的接口。
from pprint import pprint
import weakref

gc.set_debug(gc.DEBUG_UNCOLLECTABLE)
class ExpensiveObject:

    def __init__(self,name):
        self.name = name

    def __repr__(self):
        return 'ExpensiveObject({})'.format(self.name)

    def __del__(self):
        print('    (Deleting {})'.format(self))

def demo(cache_factory):
    # Hold objects so any weak references
    # are not removed immediately.
    all_refs = {}
    # Create the cache using the factory.
    print('CACHE TYPE:',cache_factory)
    cache =cache_factory()
    for name in ['one','two','three']:
        o = ExpensiveObject(name)
        cache[name] = o
        all_refs[name] = o
        del o      # decref

    print('  all_refs =',end=' ')
    pprint(all_refs)
    print('\n Before,cache contains:',list(cache.keys()))
    for name,value in cache.items():
        print('   {} = {}'.format(name,value))
        del value   # decref

    # Remove all references to the objects except the cache.
    print('\n Cleanup:')
    del all_refs
    gc.collect()

    print('\n  After,cache contains:',list(cache.keys()))
    for name,value in cache.items():
        print('   {} = {}'.format(name,value))
    print('  demo returning')

demo(dict)
print()

demo(weakref.WeakValueDictionary)

如果循环变量指示所缓存的值,那么这些循环变量必须被显示清除,以使对象的引用数减少。否则,垃圾回收器不会删除这些对象,它们仍然会保留在缓存中。类似地,all_refs变量用来保存引用,以防止它们被过早地垃圾回收。
运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值