views:

67

answers:

2
+1  Q: 

MSIL Memory Leaks

Hi All

We are using a custom RuntimeDataBuilder class that dynamically constructs a .NET type in-memory using Reflection.Emit to create simple property getters/setters for the information that we receive from a generic WCF DataService. The service exposes a "DataSet like" structure consisting out of 1..m DataTableDefinitions each containing 1..m DataTableColumnDefinitions. When the information is received client side, we generate the type with its property setters/getters to improve the performance and facilitate binding on our Silverlight client. All of this works fine.

My question is related to the possible memory leak associated with regenerating the type. From time to time the user can change the query parameters which may then result in more/less information coming across the wire. It therefore invalidates the previous type that we have created and I want to make sure that we are able to free up the memory used by this previous type definition. From this article on MSDN I gather that if you are using Light Weight Code Generation (LCG) the code is allocated on the managed heap which will be reclaimed by the GC when there is nothing holding a reference to it. But LCG only seems to apply to dynamic methods. My concern is for the Type with all its property getters/setters that is now not required anymore. If this is allocated on the unmanaged heap our only hope for reclaiming the memory seems to be to make sure that the type is loaded into a temporary AppDomain that we can unload when it is not required anymore.

Can somebody please confirm or highlight another way of reclaiming the memory.

Thx

+3  A: 

You're correct in thinking that dynamic Types will stay in memory once they have been loaded into an AppDomain. And as you say, the only way to be able to unload them from a Process is to host them in a seprate AppDomain that you can then unload in its entirety. But you have to be careful even there: make sure that references to the Type don't leak across into your main AppDomain, or these will cause it to stay in memory.

There are two links from the dawn of the CLR that you might find useful: Unloading an Assembly and Why isn't there an Assembly.Unload method?.

Have you looked at the DLR? It might be that something like ExpandoObject can help you out, although it looks like that isn't currently supported for data binding in Silverlight 4 (maybe in Silverlight 5?)

Samuel Jack
The ExpandoObject certainly is an option but as you mentioned not supported in SL4. Thx for the confirmation though.
Carel
+2  A: 

.NET 4.0 introduces concept of collectible assemblies, that are eligible for garbage collection. Usage sample can be found here.

desco
Unfortunately, collectible assemblies are not currently supported by Silverlight which is where the problem is happening (I deduce this lack of support because the necessary RunAndCollect flag is missing from the AssemblyBuilderAccess enumeration in the Silverlight 4 docs: http://msdn.microsoft.com/en-us/library/2e88sa1d(v=VS.100).aspx)
Samuel Jack
that's sad. In that case yes - generated assemblies will remain in memory and will be removed only when containing AppDomain will be unloaded.
desco
Wasn't aware of the collectible assemblies. Good to know about its existence. Sad that it isn't supported in SL though.
Carel