我真的很喜欢WeakReference。但是我希望有一种方法可以告诉CLR多少(比如,在1到5的范围内)你认为参考的程度有多弱。那将是辉煌的。
Java有SoftReference,WeakReference,我相信第三种类型称为“幻像引用”。这就是那里的3个级别,GC在确定该对象是否获得切割时具有不同的行为算法。
我正在考虑对.NET的WeakReference进行子类化(幸运的是,并且稍微有点不好意思,它没有被密封)来创建一个基于到期计时器的伪SoftReference。
答案 0 :(得分:19)
我认为NET没有软引用的根本原因是因为它可以依赖具有虚拟内存的操作系统。 Java进程必须指定其最大操作系统内存(例如,使用-Xmx128M
),并且从不需要更多的操作系统内存。而NET进程不断获取所需的操作系统内存,而当内存不足时,操作系统会提供磁盘支持的虚拟内存。如果.NET允许软引用,那么.NET运行时将不知道何时释放它们,除非它深入到操作系统以查看其内存是否实际在磁盘上分页(一个令人讨厌的OS / CLR依赖),或者它要求运行时指定最大进程内存占用量(例如,等效于-Xmx
)。我想微软不想将-Xmx
添加到NET,因为他们认为操作系统应该决定每个进程获得多少RAM(通过选择在RAM或磁盘上保存哪些虚拟内存页),而不是进程本身
答案 1 :(得分:12)
Java SoftReferences用于创建内存敏感的缓存(它们不起作用)。
从.NET 4开始,.NET有一个类System.Runtime.Caching.MemoryCache,它可能满足任何这样的需求。
答案 2 :(得分:4)
我的猜测为什么这不存在就已经很简单了。我认为,大多数人都认为只有一种类型的参考,而不是四种参考。
答案 3 :(得分:4)
WeakReference具有不同级别的弱点(优先级)听起来不错,但也可能使GC的工作更难,而不是更容易。 (我不知道GC内部,但是)我会假设为WeakReference对象保留了某种额外的访问统计信息,以便GC可以有效地清理它们(例如它可能会删除最少使用的项目)第一)。
增加的复杂性很可能不会使任何事情变得更有效,因为最有效的方法是首先摆脱不经常使用的WeakReferences。如果你可以分配优先权,你会怎么做?这听起来像是一个不成熟的优化:程序员大部分时间都不知道并且正在猜测;结果是GC收集周期较慢,可能会回收错误的对象。
但问题是,如果您关心正在回收的WeakReference.Target对象,它是否真的很好地利用了WeakReference?
它就像一个缓存。你将东西推入缓存并要求缓存在x分钟后使其变得陈旧,但大多数缓存从不保证完全保留它。它只是保证,如果确实如此,它将根据所要求的政策到期。
答案 4 :(得分:3)
也许ASP.NET Cache类(System.Web.Caching.Cache)可能有助于实现您的目标?如果内存不足,它会自动删除对象:
这篇文章介绍了如何在Windows窗体应用程序中使用Cache类。
答案 5 :(得分:2)
不要忘记您还有标准参考(您每天使用的参考)。这为您提供了一个级别。
当你不关心对象是否消失时,应该使用WeakReferences,而当你使用普通引用时,真的只应该使用SoftReferences,但是你宁愿清除你的对象然后让你用完记忆。我不确定具体细节,但我怀疑GC在确定哪些对象存在时通常会跟踪SoftReferences而不是WeakReferences,但是当内存不足时也会跳过SoftReferences。我的猜测是.Net设计师认为差异让大多数人感到困惑,或者SoftReferences增加了比他们真正想要的更多的复杂性,因此决定将它们排除在外。
作为旁注,AFAIK PhantomReferences主要供虚拟机内部使用,不适合客户实际使用。
答案 6 :(得分:1)
也许应该有一个属性,您可以在其中指定对象> =在收集之前的哪一代。因此,如果指定1,那么它是最弱的参考。但是如果你指定3那么它就需要在至少3个先前的集合中存活才能被考虑用于集合本身。
我认为轨道重新标记对此没有好处,因为到那时候对象已经完成了?可能是错的......
(PS:我是OP,刚刚注册.PITA它没有从“未注册”帐户继承您的历史记录。)
答案 7 :(得分:0)
正在寻找传递给构造函数的'trackResurrection'选项吗?
GC课程也提供一些帮助。
答案 8 :(得分:0)
不知道为什么.NET没有Softreferences。 但在Java Softreferences中恕我直言。原因至少在应用服务器中,您希望能够影响每个应用程序您的Softreferenzen生存多长时间。这在Java中是不可能的。