我熟悉WeakReference
,但我正在寻找一种仅在内存不足时才清除的引用类型,而不仅仅是每次 gc 运行时(就像 Java 一样SoftReference
)。我正在寻找一种实现内存敏感缓存的方法。
5 回答
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 上的设置器,以确保任何新目标都进入缓存。
也许 ASP.NET 缓存类 ( System.Web.Caching.Cache ) 可能有助于实现您想要的?如果内存不足,它会自动删除对象:
这是一篇文章,展示了如何在 Windows 窗体应用程序中使用 Cache 类。
除了 ASP.NET 缓存之外,还有来自 Microsoft 模式和实践组的缓存应用程序块。
尽管 aSoftReference
似乎是一种实现内存缓存的便捷方式,但它需要 Java 运行时做出一些武断的决定,以确定保留对象的好处是否超过存储它的成本。不幸的是,运行时有关保留对象的实际成本的信息有限(请记住,实际成本可能包括应用程序的内存使用对其他应用程序的影响),并且实际上没有关于保留对象的好处的信息.
如果即使不存在对它的外部强引用,也值得保留一个对象,那么缓存应该保留对它的强引用(至少只要它看起来有价值)。如果将对象保存在缓存中的好处只会在外部引用存在的情况下扩展(例如,因为生成实例很便宜,但是拥有两个保存相同数据的逻辑实体使用相同的实例来保存它们将有助于这些实体之间的比较),应该使用WeakReference
.
顺便说一句,如果我有我的 druthers,.net 将支持另一种我在任何平台上都没有见过的引用:“其他人感兴趣的”引用,它将与WeakReference
. “其他人感兴趣”的引用可以用作强引用,但WeakReference
如果对其目标的唯一强引用是“其他人感兴趣”,则适当配置的引用将无效。在使用并发 GC 时,这样的概念可以提高效率,在弱事件处理程序会重复生成对其目标的强引用的情况下。如果没有人真正对事件处理程序对其目标所做的事情感兴趣,那么如果处理程序可以取消订阅,那将是可取的。
不,没有等价物。有没有什么特别的原因为什么WeakReference
不做这项工作?
这是一个与您类似的问题: