在.NET中与SoftReference相等的是什么?

6

我熟悉WeakReference,但我正在寻找一种只在内存不足时才清除的引用类型,而不是每次垃圾回收运行时都清除(就像Java的SoftReference)。 我正在寻找一种实现内存敏感缓存的方法。

5个回答

3
ASP.NET缓存提供了您想要的内存敏感行为,但缺点是每个对象都需要一个唯一的键。然而,您应该能够保存对放置在ASP.NET缓存中的对象的WeakReference。缓存的强引用将使GC保持不变,直到缓存决定需要清除以释放内存。WeakReference使您可以访问对象,而无需使用缓存键进行查找。
Foo cachedData = new Foo();
WeakReference weakRef = new WeakReference( cachedData );
HttpRuntime.Cache[Guid.NewGuid().ToString()] = cachedData;

...

if ( weakRef.IsAlive )
{
    Foo strongRef = weakRef.Target as Foo;
}

您可以通过扩展WeakReference类来创建一个SoftReference类,具体如下所示:
class SoftReference : WeakReference
{
    public SoftReference( object target ) : base( target )
    {
        HttpRuntime.Cache[Guid.NewGuid().ToString()] = target; 
    }
}

您还需要重写Target的setter方法,以确保任何新的目标都进入缓存。


2

2

1

虽然SoftReference可能看起来是实现内存缓存的方便方式,但它需要Java运行时对是否保留对象进行某种程度的任意决定,以确定保留对象的好处是否超过存储它的成本。不幸的是,运行时对于保留对象的真实成本有限的了解(请记住,真实成本可能包括应用程序的内存使用对其他应用程序的影响),并且几乎没有关于保留对象好处的信息。

如果即使在没有外部强引用的情况下保留对象仍然值得,缓存应该保持对它的强引用(至少在它似乎值得的时间内)。如果仅当外部引用存在时从将对象保留在缓存中获得好处时(例如,因为生成实例很便宜,但具有相同数据的两个逻辑实体使用相同的实例来保存它们将有助于这些实体之间的比较),则应使用WeakReference

顺便提一下,如果我能自己选择的话,.net应该支持另一种引用类型,这种类型在任何平台上都没有见过:一个“对其他人有兴趣”的引用,它将与一种WeakReference类型一起使用。 “对其他人有兴趣”的引用可以被用作强引用,但是如果指向其目标的唯一强引用是“对其他人有兴趣”的引用,则适当配置的WeakReference将无效。这样的概念可以在使用并发GC时提高效率,在弱事件处理程序反复生成对其目标的强引用的情况下。如果没有人真正关心事件处理程序正在执行什么操作,那么最好让处理程序取消订阅。

0

3
Tony说他想实现一个内存敏感的缓存机制。但是MSDN对WeakReferences有这样的描述:"避免使用弱引用作为内存管理问题的自动解决方案。相反,应为处理应用程序对象开发有效的缓存策略。" - Evgeniy Berezovsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接