为什么 .NET 不像 Java 那样拥有 SoftReference 和 WeakReference?

发布于 2024-07-09 16:20:11 字数 285 浏览 9 评论 0原文

我真的很喜欢 WeakReference。 但我希望有一种方法可以告诉 CLR 您认为该引用有多弱(例如,按 1 到 5 的等级)。 那真是太棒了。

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

我正在考虑对 .NET 的 WeakReference 进行子类化(幸运的是,有点奇怪的是它没有被密封)来创建一个基于过期计时器或其他东西的伪 SoftReference。

I really love WeakReference's. But I wish there was a way to tell the CLR how much (say, on a scale of 1 to 5) how weak you consider the reference to be. That would be brilliant.

Java has SoftReference, WeakReference and I believe also a third type called a "phantom reference". That's 3 levels right there which the GC has a different behaviour algorithm for when deciding if that object gets the chop.

I am thinking of subclassing .NET's WeakReference (luckily and slightly bizzarely it isn't sealed) to make a pseudo-SoftReference that is based on a expiration timer or something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

祁梦 2024-07-16 16:20:11

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

I believe the fundamental reason that NET does not have soft references is because it can rely on an operating system with virtual memory. A Java process must specify its maximum OS memory (e.g. with -Xmx128M), and it never takes more OS memory than that. Whereas a NET process keeps taking OS memory that it needs, which the OS supplies with disk-backed virtual memory when RAM runs out. If NET allowed soft references, then the NET runtime would not know when to release them unless it either peeked deep into the OS to see if its memory is actually paged on disk (a nasty OS/CLR dependency), or it requested the runtime to specify a maximum process memory footprint (e.g. an equivalent of -Xmx). I guess that Microsoft does not want to add -Xmx to NET because they think the OS should decide how much RAM each process gets (by choosing which virtual memory pages to hold in RAM or on disk), and not the process itself.

转角预定愛 2024-07-16 16:20:11

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

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

Java SoftReferences are used in the creation of memory sensitive caches (they serve no other purpose).

As of .NET 4, .NET has a class System.Runtime.Caching.MemoryCache which will probably meet any such needs.

烦人精 2024-07-16 16:20:11

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

增加的复杂性很可能不会提高任何效率,因为最有效的方法是首先摆脱不常用的弱引用。 如果你可以指定一个优先级,你会怎么做? 这听起来像是一种过早的优化:程序员大多数时候并不真正知道,而是在猜测; 结果是 GC 收集周期变慢,可能回收了错误的对象。

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

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

Having a WeakReference with varying levels of weakness (priority) sounds nice, but also might make the GC's job harder, not easier. (I've no idea on the GC internals, but) I would assume there some sort of additional access statistics that are kept for WeakReference objects so that the GC can clean them up efficiently (e.g. it might get rid of the least-used items first).

More than likely the added complexity wouldn't make anything any more efficient because the most efficient way is to get rid of infrequently used WeakReferences first. If you could assign a priority, how would you do it? This smells like a premature optimization: the programmer doesn't really know most of the time and is guessing; the result is a slower GC collection cycle that is probably reclaiming the wrong objects.

It begs the question though, that if you care about the WeakReference.Target object being reclaimed, is it really a good use of WeakReference?

It's like a cache. You shove stuff into the cache and ask the cache to make it stale after x minutes, but most caches never guarantee to keep it around at all. It just guarantees that if it does, it will expire it according to the policy requested.

2024-07-16 16:20:11

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

My guess as to why this isn't there already would be simplicity. Most people, I think, would call it a virtue that there is only one type of reference, not four.

滴情不沾 2024-07-16 16:20:11

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

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

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

Maybe the ASP.NET Cache class (System.Web.Caching.Cache) might help achieve what you want? It automatically remove objects if memory gets low:

Here's an article that shows how to use the Cache class in a windows forms application.

quoted from: Equivalent to SoftReference in .net?

南风几经秋 2024-07-16 16:20:11

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

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

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

顺便说一句,据我所知,PhantomReferences 主要是为虚拟机内部使用而设计的,而不是为实际客户端使用而设计的。

Don't forget that you also have your standard references (the ones that you use on a daily basis). This gives you one more level.

WeakReferences should be used when you don't really care if the object goes away, while SoftReferences really only should be used when you would use a normal reference, but you would rather your object be cleared then for you to run out of memory. I'm not sure on the specifics, but I suspect that the GC normally traces through SoftReferences but not WeakReferences when determining which objects are live, but when running low on memory will also skip the SoftReferences.

My guess is that the .Net designers felt that the difference was confusing to most people and or that SoftReferences add more complexity than they really wanted and so decided to leave them out.

As a side note, AFAIK PhantomReferences are mostly designed for internal use by the virtual machine and are not intended for actual client use.

巾帼英雄 2024-07-16 16:20:11

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

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

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

Maybe there should be an property where you can specify which Generation that the object >= before it is collected. So if you specify 1 then it is the weakest possible reference. But if you specify 3 then it would need to survive at least 3 prior collections before it can be considered for collection itself.

I thought the track ressurection flag was no good for this because by that time the object has already been finalized? May be wrong though...

(PS: I am the OP, just signed up. PITA that it doesn't inherit your history from "unregistered" accounts.)

£噩梦荏苒 2024-07-16 16:20:11

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

GC 类也提供了一些帮助。

Looking for the 'trackResurrection' option passed to the constructor perhaps?

The GC class also offers some assistance.

桃扇骨 2024-07-16 16:20:11

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

Don't know why .NET does not have Softreferences.
BUT in Java Softreferences are IMHO overused. The reason is tha at least in an application server you would want to be able to influence per application how long your Softreferenzen live. That's currently not possible in Java.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文