Why doesn't .NET have a SoftReference as well as a WeakReference, like Java?
Asked Answered
P

9

19

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.

Putout answered 27/11, 2008 at 20:52 Comment(1)
Maybe if you explain what problem you're trying to solve, you'll might get some answers with good solutions. Usually it's not a good idea to work at this level of granularity and some form of expiration cache is more appropriate, but it all depends on the problem.Simsar
M
19

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.

Malevolent answered 18/8, 2011 at 4:21 Comment(1)
But maybe for .Net Compact such thing could be useful.Namedropping
S
12

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.

Sauropod answered 15/9, 2012 at 17:20 Comment(3)
This is a really good pointer and aught to be at the top of the answers.Vickievicksburg
Its a nice addition, but I wonder at its flexibility. I am generally in favor of exposed mechanisms over dealer black boxes. They tend to be more useful in real world production. (Granted GC itself is a sealed black box generally, but at least Java lets you replace the whole collector if you really want to.)Vickievicksburg
I agree, as a general point - I prefer exposed mechanisms to black boxes, which is one reason I much prefer Java to C#. But on the other hand, every new java garbage collector requires its own implementation of SoftReferences which might easily be less fit-for-your-purposes than your current GC. And changing GC is not an undertaking to be taken lightly (at least, in a low-pause/low-latency environment).Sauropod
U
5

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.

Unni answered 28/11, 2008 at 1:13 Comment(3)
The difference is that using SoftReference to cache allows you to hold things as long as there is enough memory for them but dispose them if not. Its a much more efficient solution then a time out on a cache.Vickievicksburg
@Vickievicksburg I think you're missing my comment about caches. A cache could utilize WeakReference already, but staleness could also apply to cached items. From the point of the cache consumer, a cache doesn't normally guarantee items get to stay in the cache. Devs already complain about the GC, so perhaps the C# team felt that adding new levels of weak references (soft, phantom) didn't add enough. As always, Eric Lippert's blogs.msdn.com/b/ericlippert/archive/2003/10/28/… is a good read for insight into C# features.Unni
Robert, I fear you did not understand me at all. No, a cache does not guarantee things stay in the cache. Thats the point. But a cache based solely on time does not do a good job of determining what should and shouldn't be in memory. It flushes things with no reason. A cache based on memory needs is much better at preserving data unless it really needs to be removed. You COULD implement an LRU cache yourself but that would require adding pseudo-memory management code to your application. Its far more efficient to let the GC which is already managing memory manage your cache.Vickievicksburg
C
4

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.

Calycle answered 27/11, 2008 at 20:57 Comment(1)
actually SoftReferences are EXTREMELY useful as they allow for gc aware memory sensitive caching. Most people who actually understand what they re good for would like to have them. In Java code I use SoftReference MUCH more often then WeakReferenceVickievicksburg
P
3

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?

Priapism answered 18/2, 2010 at 17:13 Comment(0)
M
2

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.

Madalena answered 19/1, 2009 at 17:6 Comment(1)
See my comments above about how useful SoftRefernces are and how they can allow you to code more efficiently. Phantom References are for anyone who really needs to do post mortem cleanup of some kind.Vickievicksburg
W
1

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.)

Westbound answered 27/11, 2008 at 21:12 Comment(0)
L
0

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

The GC class also offers some assistance.

Lumbricalis answered 27/11, 2008 at 21:3 Comment(0)
M
0

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.

Maniple answered 19/1, 2009 at 16:37 Comment(1)
On HotSpot there is one option to configure this slightly: -XX:SoftRefLRUPolicyMSPerMB=xyz. See java.sun.com/docs/hotspot/HotSpotFAQ.html#gc_softrefsDecarburize

© 2022 - 2024 — McMap. All rights reserved.