2
votes

I am using Castle Windsor DI container in my WCF app server. In this case the lifetime is per-request: a new service instance is created, container is created and installed, some components are resolved, come work is done and all is disposed.

However, after some amount of requests there is increasing memory consumption of my app server. I was able to find out when I comment out the DI usage the memory problems disappear. But when I install the container and resolve some component, there are some "memory leaks". I found some articles and posts talking about lifecycles. But all of them are bound to container instance. Since my container lives just during the request there must be everything destroyed when disposing it.

My service implements IDisposable and in the Dispose method I call the container.Dispose as well. However memory usage grows on and on.

Using dotMemory profiler I can see there are survivors and new instances of ProxyGenerationOptions and some other classes.

dotMemory snapshots comparison

Am I missing something? Why the container is not releasing all used memory after Dispose is called?

1
Do you see the same issue if you use Windows permon? The reason I'm asking the memory leak is not the same as excessive memory usage. In other words are you confident it is a "leak"? - Spock
I believe it really is a leak. All counters show increasing memory consumption. Moreover the dotMemory shows explicit number of instances of same Castle.* classes that are living in memory and that number increases after each request (container create - install - resolve - dispose). I thought after container.Dispose there all Castle.* objects will be garbage collected. - Jan Drozen
Who holds them in memory? Open Group by Similar retention" for all ProxyGenerationOption object set. Or open one instance and "Key Retention Path" view - Ed Pavlov
Ed.ward: the retention path shows only "Static reference". Screenshot: dropbox.com/s/mjfuy0uw0fp27rs/keyRetention.png?dl=0 - Jan Drozen
This is quite strange for me - how is it possible to on each request store new static reference while keepink the old one? I have an idea: on each request I can see in output in debugger Loaded 'DynamicProxyGenAssembly2'. Isn't it possible, that the static reference is being hold in this assembly and on each request is generated and JITed new assembly which gets never unloaded? - Jan Drozen

1 Answers

1
votes

I had a similar problem I solved it, when I created the proxy class, I served the ModuleScope object

public static class ProxyFactory
{
    private static ModuleScope _moduleScope = new ModuleScope(false, false);

    public static TClass CreateProxy<TClass>(TClass instance) 
    {

                ProxyGenerator proxy = new ProxyGenerator(new DefaultProxyBuilder(_moduleScope));


                List<Type> interfaces = new List<Type>();       
                interfaces.AddRange(instance.GetType().GetInterfaces());

TClass result = proxy.CreateClassProxyWithTarget(
                instance.GetType(),
                interfaces.ToArray(),
                instance, ......

   }

}