为什么.NET没有像Soft一样的SoftReference和WeakReference?

17 c# weak-references soft-references

我真的很喜欢WeakReference.但我希望有一种方法可以告诉CLR多少(比如说,在1到5的范围内)你认为参考的程度有多弱.那将是辉煌的.

Java有SoftReference,WeakReference,我相信第三种类型称为"幻像引用".这就是那里的3个级别,GC在决定该对象是否获得切割时具有不同的行为算法.

我正在考虑对.NET的WeakReference进行子类化(幸运的是,并且稍微有点不好意思,它没有密封)来创建一个基于到期计时器或其他东西的伪SoftReference.

小智 19

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


bar*_*itt 12

Java SoftReferences用于创建内存敏感的缓存(它们不用于其他目的).

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


Rob*_*son 5

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

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

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

它就像一个缓存。您将东西放入缓存并要求缓存在 x 分钟后使其失效,但大多数缓存根本不保证将其保留。它只是保证如果这样做,它将根据请求的策略使其过期。

  • 罗伯特,恐怕你根本不了解我。不,缓存并不能保证东西留在缓存中。这才是重点。但是仅基于时间的缓存并不能很好地确定应该和不应该在内存中的内容。它无缘无故地冲洗东西。除非确实需要删除数据,否则基于内存需求的缓存在保留数据方面要好得多。您可以自己实现 LRU 缓存,但这需要向您的应用程序添加伪内存管理代码。让已经在管理内存的 GC 管理您的缓存更有效。 (2认同)

The*_*urf 4

我对为什么不存在的猜测很简单。我认为,大多数人会认为只有一种而不是四种参考是一种美德。

  • 实际上,SoftReferences 非常有用,因为它们允许 gc 感知的内存敏感缓存。大多数真正了解它们的用途的人都希望拥有它们。在 Java 代码中,我使用 SoftReference 的频率比 WeakReference 多得多 (7认同)