Jeff
Jeff

Reputation: 36573

Windsor TypedFactoryInterceptor Memory Leak

I believe there is a memory leak with the TypedFactoryInterceptor.

Please consider the following scenario:

[Factory]
public interface IMyFactory 
{
     MySingleton GetInstance();
}

[Singleton]
public class MySingleton
{
}

[Singleton]
public class MyController
{
    public MyController(IMyFactory factory)
    {
        // using a for loop to simulate repeated calls to the factory instance over
        // a long time
        for(int i = 0; i < 100000; i++)
        {
            var instance = factory.GetInstance();
        }
    }
}

In the above example, the TypedFactoryInterceptor will contain a list of 100000 WeakReferences, all of which point to the same Target instance (of MySingleton). So, in the scenario where one singleton depends of a factory to create instances of another singleton, you can end up with hundreds of thousands of WeakReferences and thus a memory leak.

In doing some looking at the source code, it looks like the problem is here (in TypedFactoryInterceptor.Resolve):

// this is called on every Resolve call to the TypedFactory (IMyFactory.GetInstance)
if (this.kernel.ReleasePolicy.HasTrack(instance))
{
    // there will not be any dead references because MySingleton is a Singleton
    this.CollectDeadReferences();
    // adds another WeakReference to the same Singleton instance
    this.resolvedTrackedComponents.Add(new WeakReference(instance));
}

Any thoughts?

Thanks.

Upvotes: 0

Views: 300

Answers (1)

Krzysztof Kozmic
Krzysztof Kozmic

Reputation: 27374

That is a result of the trick with WeakReferences being a workoaround for architectural limitations in Windsor 2.5 rather than a full blown solution.

This is fixed in (upcoming) Windsor 3, where no WeakReferences are involved.

As a temporary workaround I guess your best option is to not use a factory for that singleton (or upgrade to Windsor 3).

Upvotes: 1

Related Questions