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.
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
{
{
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
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