1
votes

I'm using Castle Windsor and DynamicProxy to implement persistence Lazy Loading from scratch (I know NHibernate could be an option etc.) I have implemented a custom component activator to always instantiate my business classes as proxies.

I had my doubts concerning the component activator lifestyle (What is the expected LifeStyle of a Castle Windsor component activator?). Krzysztof Kozmic kindly answered that "Every component in Windsor will get its own activator instance".

Faced with a big memory leak in my application I have come to find that an explicit destructor in this class is never called (in my case at least). Is Castle freeing the activators appropriately, namely, when the typed factory is disposed?

Classes
    .FromAssemblyContaining(typeof(QuantityType))
    .InNamespace(typeof(QuantityType).Namespace)
    .WithService.DefaultInterfaces()
    .Configure(reg => { reg.Activator<ColMsProxyComponentActivator>(); })
    .LifestyleTransient() // We really want new entities every time a new one is requested

As a side note, would it not be useful to have the ability to explicitly declare the component activator lifestyle? In my case, there's no reason why it can't be a Singleton, and that would save some memory and processing.

1

1 Answers

2
votes

The most common reason for perception of memory leak in castle Windsor is the misunderstanding of how to deal with any component that doesn't have a system definable lifetime, most notably, transient components.

The designers of castle decided that the responsibility for both creation and destruction are the container's concerns. That being the case, the default behavior is to track all objects the container creates. That means, if you don't release them, you're going to see what looks like a memory leak.

If you read this and are thinking "I know, I know, I'm releasing all my stuff", you might want to prove to yourself you are by changing the default release policy to "don't track". If your memory leak goes away you probably aren't releasing something somewhere.

I think this is the code for changing the release policy:

 container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();

If you're thinking, I'll just leave that NoTrackingReleasePolicy on because it solves my issue, here's a note from the authors in the code:

 [Obsolete("This class is a hack, will be removed in the future release and should be avoided. Please implement proper lifecycle management instead.")]

Here's a useful link about releasing objects if you're unaware how it all works

Hope this helps