19

我真的很喜欢 WeakReference 的。但我希望有一种方法可以告诉 CLR 多少(例如,在 1 到 5 的范围内)您认为该引用有多弱。那将是辉煌的。

Java 有 SoftReference、WeakReference,我相信还有第三种类型,称为“幻像引用”。那是 3 个级别,GC 在决定该对象是否获得印章时具有不同的行为算法。

我正在考虑将.NET 的 WeakReference 子类化(幸运的是,它没有被密封)来制作一个基于过期计时器或其他东西的伪 SoftReference。

4

9 回答 9

19

我认为 NET 没有软引用的根本原因是因为它可以依赖具有虚拟内存的操作系统。Java 进程必须指定它的最大操作系统内存(例如用-Xmx128M),并且它永远不会占用比这更多的操作系统内存。而 NET 进程不断占用它需要的操作系统内存,当 RAM 用完时,操作系统会提供磁盘支持的虚拟内存。如果 NET 允许软引用,那么 NET 运行时将不知道何时释放它们,除非它深入操作系统以查看其内存是否实际在磁盘上分页(讨厌的 OS/CLR 依赖项),或者它请求运行时指定最大进程内存占用(例如,相当于-Xmx)。我猜微软不想添加-XmxNET,因为他们认为操作系统应该决定每个进程获得多少 RAM(通过选择将哪些虚拟内存页面保存在 RAM 或磁盘上),而不是进程本身。

于 2011-08-18T04:21:05.320 回答
12

Java SoftReferences 用于创建内存敏感缓存(它们没有其他用途)。

从 .NET 4 开始,.NET 有一个System.Runtime.Caching.MemoryCache类,它可能会满足任何此类需求。

于 2012-09-15T17:20:21.277 回答
5

具有不同程度的弱点(优先级)的 WeakReference听起来 不错,但也可能会使 GC 的工作更难,而不是更容易。(我不知道 GC 的内部结构,但是)我会假设为 WeakReference 对象保留了某种额外的访问统计信息,以便 GC 可以有效地清理它们(例如,它可能会删除最少使用的项目第一的)。

增加的复杂性很可能不会使任何事情变得更有效,因为最有效的方法是首先摆脱不经常使用的 WeakReferences。如果你可以指定一个优先级,你会怎么做?这听起来像是过早的优化:程序员大部分时间并不真正知道并且在猜测;结果是较慢的 GC 收集周期,可能是回收了错误的对象。

但它引出了一个问题,如果你关心被回收的 WeakReference.Target 对象,它真的是 WeakReference 的好用处吗?

这就像一个缓存。您将内容塞入缓存并要求缓存在 x 分钟后使其陈旧,但大多数缓存根本不保证将其保留。它只是保证如果确实如此,它将根据请求的策略将其过期。

于 2008-11-28T01:13:19.920 回答
4

我对为什么不存在的猜测很简单。我想,大多数人都会把它称为一种美德,即只有一种类型的参考,而不是四种。

于 2008-11-27T20:57:41.697 回答
3

也许 ASP.NET 缓存类 (System.Web.Caching.Cache) 可能有助于实现您想要的?如果内存不足,它会自动删除对象:

这是一篇文章,展示了如何在 Windows 窗体应用程序中使用 Cache 类。

引自:相当于.net中的SoftReference?

于 2010-02-18T17:13:03.277 回答
2

不要忘记您也有您的标准参考资料(您每天使用的参考资料)。这给了你一个更高的层次。

当您并不真正关心对象是否消失时,应该使用 Wea​​kReferences,而 SoftReferences 只应该在您使用普通引用时使用,但您宁愿清除您的对象以便您耗尽内存。我不确定具体细节,但我怀疑 GC 在确定哪些对象处于活动状态时通常会通过 SoftReferences 而不是 WeakReferences 进行跟踪,但是当内存不足时也会跳过 SoftReferences。

我的猜测是 .Net 设计者觉得这种差异让大多数人感到困惑,或者 SoftReferences 增加了比他们真正想要的复杂性更多的复杂性,因此决定将它们排除在外。

附带说明一下,AFAIK PhantomReferences 主要是为虚拟机内部使用而设计的,而不是供实际客户端使用的。

于 2009-01-19T17:06:14.697 回答
1

也许应该有一个属性,您可以在其中指定对象 >= 在收集之前的哪个世代。所以如果你指定 1 那么它是最弱的参考。但是,如果您指定 3,那么它需要在之前的至少 3 个集合中存活下来,然后才能考虑将其用于集合本身。

我认为轨道恢复标志对此没有好处,因为到那时对象已经完成了?虽然可能是错的...

(PS:我是OP,刚刚注册。PITA,它不会从“未注册”帐户继承您的历史记录。)

于 2008-11-27T21:12:43.197 回答
0

不知道为什么 .NET 没有软引用。但在 Java 软引用中,恕我直言,过度使用。原因是至少在应用程序服务器中,您希望能够影响每个应用程序的 Softreferenzen 存活时间。目前这在 Java 中是不可能的。

于 2009-01-19T16:37:18.170 回答
0

寻找传递给构造函数的“trackResurrection”选项?

GC 类也提供了一些帮助。

于 2008-11-27T21:03:18.020 回答