Search code examples
c#memory-leaksgarbage-collectionweak-references

Can the value of a ConditionalWeakTable cause a memory leak?


If the value for an entry in a ConditionalWeakTable has a reference to its key, does it prevent the key from being garbage collected?

Let's say you have an interface and a decorator for that interface. The decorator holds a reference to what it decorates.

public interface IFoo
{
}

public class FooDecorator : IFoo
{
    private readonly IFoo _foo;

    public FooDecorator(IFoo foo)
    {
        _foo = foo;
    }
}

And let's say that you have a extension method class that uses a ConditionalWeakTable<IFoo, FooDecorator>, so that each instance of IFoo can retrieve the same instance of FooDecorator each time the extension method is called.

public static class FooExtensions
{
    private static readonly ConditionalWeakTable<IFoo, FooDecorator> _decorators =
        new ConditionalWeakTable<IFoo, FooDecorator>();

    public static IFoo GetDecorator(this IFoo foo)
    {
            return
                foo as FooDecorator // don't decorate the decorator
                ?? _decorators.GetValue(foo , f => new FooDecorator(f));
    }
}

Given:

  • that a FooDecorator exists as a value in the ConditionalWeakTable, retrievable by an instance of IFoo; and
  • that a FooDecorator holds a strong reference to the same instance of IFoo

Can the instance of IFoo ever be eligible for garbage collection? And if it not, is there a way I can use this pattern so that garbage collection is not prevented?


Solution

  • The MSDN page specifically states that

    However, in the ConditionalWeakTable class, adding a key/value pair to the table does not ensure that the key will persist, even if it can be reached directly from a value stored in the table ...

    So it will not cause the kind of leak you worry about.