OutOfMemory & CompiledAssembly


Problems seem to occur in batches. Last week the hot topic was OutOfMemory exceptions.


I got a memory dump that a customer took around the time they were getting OutOfMemory exceptions. I asked them to collect some performance counters so that we could figure out what this leak was all about.


The performance counters we got were


 



.NET CLR Loading\Current Assemblies


Process\Private Bytes


Process\Virtual Bytes


.NET CLR Memory\# Bytes in all heaps


.NET CLR Memory\# Total committed bytes


.NET CLR Memory\# Total reserved bytes


 


The picture below shows the output.


 


Perfmon


 


The line that keeps increasing matches “Current Assemblies”. Now this is strange since usually after a while this should stop increasing. So it appears we are having assembly leaking.


 


Let’s try to find what these assemblies are.


 



0:000> !DumpDynamicAssemblies


Domain: xxxxxxx


-------------------


Assembly: 0x15ba5ab0 [-fxq0b2q] Dynamic Module: 0x15bbc7c0 loaded at: 0x170a1000 Size: 0xf000((null))


Assembly: 0x15bb52f0 [m_o9jngq] Dynamic Module: 0x224830 loaded at: 0x17421000 Size: 0x26000((null))


Assembly: 0x15bb5868 [dgttiya4] Dynamic Module: 0x224ed0 loaded at: 0x17451000 Size: 0x1200((null))


Assembly: 0x1748ee30 [tfgs3roi] Dynamic Module: 0x1748b7a0 loaded at: 0x17e11000 Size: 0x1b000((null))


Assembly: 0x15bc54f0 [xw0tr4my] Dynamic Module: 0x15bc5928 loaded at: 0x1e7b1000 Size: 0x1fd000((null))


 


At the time this memory dump was taken we had almost 2000 dynamic assemblies in memory. Digging into some of these assemblies ...


 



0:000> !savemodule 0x1748b7a0  c:\leak.dll


Successfully saved file: c:\leak.dll


 


And opening them with Lutz Reflector we find a pattern


 



public class _DinAssembly


{


    public bool _method1()


    {


        return true;


    }


}


 


After talking with dev teams and doing some search in source code we found that this assembly is being generated in source code.


 



(…)


results.CompiledAssembly.CreateInstance


(…)


 


 


If you look at


http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerresults.compiledassembly.aspx


you can see


 








Note:


(…) After calling the get accessor, the compiled assembly cannot be deleted until the current AppDomain is unloaded.


 


So some possible solutions are:


·         Try some caching mechanism (if it´s possible)


·         Load this assemblies into a separated domain so that you could unload it


·         Do you really need to generate this assembly?


 


Bruno

Skip to main content