Search code examples
c#.netgarbage-collectionweak-referencessoft-references

Are C# weak references in fact soft?


The basic difference is that weak references are supposed to be claimed on each run of the GC (keep memory footprint low) while soft references ought to be kept in memory until the GC actually requires memory (they try to expand lifetime but may fail anytime, which is useful for e.g. caches especially of rather expensive objects).

To my knowledge, there is no clear statement as to how weak references influence the lifetime of an object in .NET. If they are true weak refs they should not influence it at all, but that would also render them pretty useless for their, I believe, main purpose of caching (am I wrong there?). On the other hand, if they act like soft refs, their name is a little misleading.

Personally, I imagine them to behave like soft references, but that is just an impression and not founded.

Implementation details apply, of course. I'm asking about the mentality associated with .NET's weak references - are they able to expand lifetime, or do they behave like true weak refs?

(Despite a number of related questions I could not find an answer to this specific issue yet.)


Solution

  • I have seen no information that indicates that they would increase the lifetime of the object they point to. And the articles I read about the algorithm the GC uses to determine reachability do not mention them in this way either. So I expect them to have no influence on the lifetime of the object.

    Weak
    This handle type is used to track an object, but allow it to be collected. When an object is collected, the contents of the GCHandle are zeroed. Weak references are zeroed before the finalizer runs, so even if the finalizer resurrects the object, the Weak reference is still zeroed.

    WeakTrackResurrection
    This handle type is similar to Weak, but the handle is not zeroed if the object is resurrected during finalization.

    http://msdn.microsoft.com/en-us/library/83y4ak54.aspx


    There are a few mechanism by which an object that's unreachable can survive a garbage collection.

    • The generation of the object is larger than the generation of the GC that happened. This is particularly interesting for large objects, which are allocated on the large-object-heap and are always considered Gen2 for this purpose.
    • Objects with a finalizer and all objects reachable from them survive the GC.
    • There might be a mechanism where former references from old objects can keep young objects alive, but I'm not sure about that.