views:

772

answers:

2

I understand and appreciate the usefulness of the System.WeakReference class in the .NET framework, but am curious as to the implementation details.

How is WeakReference implemented in .NET? MSDN discusses the usage of WeakReference in detail, but has little details that I've seen on how this works under the hood.

How does the CLR track the reference and know to null out the internal handle when the Target is collected, without preventing the GC? Does it require special handling in the CLR itself?

My main concern would be whether there are performance implications of using WeakReferences (especially if using many of them) that differ from those of using standard object references.

+2  A: 

You mentioned MSDN; have you already seen this article?

http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

Also check out chapter 19 in "Applied Microsoft .NET Framework Programming" by the same author (Jeffrey Richter). The chapter is on garbage collection and has a section on WeakReference internals.

In general, if you're accessing a lot of Targets within WeakReferences, then there's a performance hit simply because the WeakRef does some work (mostly for thread safety) before returning the target. This is obviously not as cheap as using the object reference directly. On the other hand, you gain some performance when storing references to large objects, since the garbage collector has more options when memory considerations arise.

I've never tried to quantify this trade off, or know of any references here. Obviously it varies somewhat depending on the application.

ars
+1, and thanks for the reference material. Just FYI, I've done more research, and there's surprisingly little overhead for thread safety in WeakReference - mostly, it's a matter of having to get GCHandle to hand back the object, which acts like dereferencing twice, plus a couple of null checks.
Reed Copsey
I thought I remembered seeing that a couple of years ago, but I really should have confirmed it before putting it down in the answer. Thanks for noting that, Reed.
ars
+5  A: 

The WeakReference class hands of it's object reference to the GC and gets a handle back. Whenever you get the reference or check if the reference is alive, the handle is used to ask the GC for the reference.

This means that the GC keeps a list of all weak references, that it has to update when objects are collected. It also means that there is some overhead every time you use a weak reference.

So, every weak reference means a little more work for the garbage collector, but on the other hand so does every regular reference too, even if it's less. You should of course be a bit careful about using a lot of weak references, but if you need that to get the memory management to work well with your objects, that should outweight the small overhead that it causes.

Guffa
I'm going to set this as the answer since it's a good, basic description of the process. Thanks Guffa.
Reed Copsey