tags:

views:

46

answers:

1

Consider the following code sample:

using System;
using System.Linq.Expressions;

public class Class1<T, Y>
{
    public Class1(Expression<Func<T, Y>> mapExpression)
    {
        GetValue = mapExpression.Compile();
    }

    public Func<T, Y> GetValue { get; protected set; }
}

public class DataClass
{
    public long Data { get; set; }
}

Now suppose that I make in different places new instances of Class1, e.g.

var instance1 = new Class1<DataClass, long>(x => x.Data);
var instance2 = new Class1<DataClass, long>(x => x.Data);

When I do this, what happens:

  1. Do I get two different compiled functions?
  2. If so, do the two compiled functions get garbage collected when the instances of Class1 get garbage collected?
  3. If not, how can I avoid a memory leak (assuming that I can't realistically control the creation of Class1 instances)?
+2  A: 
  1. Yes. Make this static if 'singleton' is required.
  2. Before .NET 4, no, with .NET 4 dynamic created assemblies/code can be garbage collect under certain conditions.
  3. If the 'singleton' pattern does not work, try using a static caching mechanism.
leppie
Thanks for the answer. In .NET 4, can you be more specific (or provide a reference) as to what the conditions are when the dynamically created code would get garbage collected?
Nathan
@Nathan: I'll have to dig into the documentation. IIRC it was 'linked' from the new features in .NET 4.
leppie
Hmm. I wonder if lamba.Compile generates a DynamicMethod? http://msdn.microsoft.com/en-us/library/system.reflection.emit.dynamicmethod%28v=VS.90%29.aspx seems to indicate that DyanmicMethods would be garbage collected, even in .NET3.5?
Nathan
@Nathan: I believe that didn't really work except in a very few cases.
leppie
@Nathan: Also in my experience, there is a 'memory leak' in ModuleBuilder, preventing GC of generated bytecode.
leppie
I wrapped the instance creation in the above code sample in a while(true) loop (compiled for .NET 3.5) and let it run for a half hour, and could see no growth in the memory usage of the application (using windows task manager). So it appears that at least for this simple case, the compiled expression does in fact get garbage collected. This still leaves me curious what situations if any could cause a "memory leak" - and what the changes between .NET 3.5 and .NET 4 garbage collection of dynamically created code are.
Nathan