python– 使用WeakValueDictionary进行缓存时GC的问题

python– 使用WeakValueDictionary进行缓存时GC的问题,第1张

概述根据weakref模块的官方Python文档,“弱引用的主要用途是实现保存大对象的缓存或映射,......”.因此,我使用WeakValueDictionary为长时间运行的函数实现缓存机制.然而,事实证明,缓存中的值从未停留在那里,直到实际再次使用它们,但几乎每次都需要重新计算.由于访问存储在WeakValueDictionary中的值之间没有强引用,因此

根据weakref模块的官方Python文档,“弱引用的主要用途是实现保存大对象的缓存或映射,……”.因此,我使用WeakValueDictionary为长时间运行的函数实现缓存机制.然而,事实证明,缓存中的值从未停留在那里,直到实际再次使用它们,但几乎每次都需要重新计算.由于访问存储在WeakValueDictionary中的值之间没有强引用,因此GC消除了它们(即使内存完全没有问题).

现在,我如何使用弱参考资料来实现缓存?如果我明确地在某处保留强引用以防止GC删除我的弱引用,那么首先使用WeakValueDictionary是没有意义的. GC可能应该有一些选项告诉它:删除所有没有引用的内容以及只有在内存不足时(或超出某个阈值时)弱引用的所有内容.有类似的东西吗?或者这种缓存有更好的策略吗?

最佳答案我将尝试用如何使用weakref模块实现缓存的示例来回答您的询问.我们将缓存的弱引用保存在weakref.WeakValueDictionary中,以及collections.deque中的强引用,因为它有一个maxlen属性来控制它所持有的对象数.在函数闭包样式中实现:

import weakref,collectionsdef createLRUCache(factory,maxlen=64):    weak = weakref.WeakValueDictionary()    strong = collections.deque(maxlen=maxlen)    notFound = object()    def fetch(key):        value = weak.get(key,notFound)        if value is notFound:            weak[key] = value = factory(key)        strong.append(value)        return value    return fetch

deque对象只保留最后的maxlen条目,只要在达到容量时删除对旧条目的引用.当删除旧条目并通过python收集垃圾时,WeakValueDictionary将从映射中删除这些键.因此,两个对象的组合有助于我们在LRU缓存中仅保留maxlen条目.

class Silly(object):    def __init__(self,v):        self.v = vdef fib(i):    if i > 1:        return Silly(_fibcache(i-1).v + _fibcache(i-2).v)    elif i: return Silly(1)    else: return Silly(0)_fibcache = createLRUCache(fib)
总结

以上是内存溢出为你收集整理的python – 使用WeakValueDictionary进行缓存时GC的问题全部内容,希望文章能够帮你解决python – 使用WeakValueDictionary进行缓存时GC的问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1205726.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存