Charly Paris
Charly Paris

Reputation: 71

EF DbContext memory not released

I can't free proc memory used by my EF DbContext. In spite of dispose and GC.Collect, my application don't free memory.

I created a little program :

static void Main(string[] args)
{

    var test = new TestDb();
    System.Threading.Thread.Sleep(1000);

    // Here proc memory = 7 Mo

    test.Fill();
    System.Threading.Thread.Sleep(1000);

    // Here proc memory = 58 Mo

    test.Dispose();
    System.Threading.Thread.Sleep(1000);

    // Here proc memory = 37.8 Mo

    test = null;
    GC.Collect();

    // Here proc memory = 37.8 Mo
    // Why is not 0 here ???

    System.Threading.Thread.Sleep(1000);
}

You can show memory usage with my comments.

TestDb Class :

 public class TestDb : IDisposable
{
    private List<TaskAction> _actions;

    public void Fill()
    {
        using (var entities = new myEntities())
        {
            entities.Configuration.LazyLoadingEnabled = false;
            _actions = entities.TaskActions.ToList();
        }
    }

    public void Dispose()
    {
        _actions = null;
        GC.Collect();
    }
}

How can I free all used memory ??

Thanks,

Charly

Upvotes: 1

Views: 749

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062600

If we just focus on data memory: the runtime doesn't hand memory back to the OS unless there's a good reason; if you've just been using {some amount of memory}, there's a very good chance you're going to be using that again in a moment, and it is much more efficient to keep hold of it for a while. GC.Collect just deals with internal book keeping so that it doesn't have to ask for more memory from the OS any time soon. There are things you can do to make the runtime more aggressive in returning memory, but... 37Mb is basically nothing.

Additionally, it still takes memory for the internal .NET bits (type metadata, all the assemblies you've loaded, JIT, IL, etc). Doing something, anything with EF (or any other library) is going to tie up some memory in the process that will not be released. And since you've talked to the database, there's also probably now a connection pool (managed and unmanaged), and some SQL-related threads.

Upvotes: 3

Related Questions