How you should easily prevent this memory leak with EF Core

Entity Framework core, as the most used .net core ORM (object-relational mapping) framework, simplify the developer’s life by managing its database access complexity.

However, as it usually happens, such simplification comes with a price. In most cases, the price is flexibility and performance.

1.Simplicity is a trap

Injecting the database context in the built-in IoC container is as quick as the following:

The TodoContext becomes then accessible from anywhere needed in you application, to create, read, update or delete any data from your database provider.

The issue arises quickly when you have a different need than responding to an Http request, a background worker for example:

Background job containing a memory leak

If you don’t have enough knowledge of ASP.NET core and of the behaviors of EFcore, the leak is hard to spot:

  • DBContext objects tracking: during the lifetime of the context, all the manipulated entities are kept and tracked by default in the context object.

  • Dependency Injection scope: Each http request triggers the creation of a scope to resolve dependencies from. At the end of the request, the scope and the related dependencies will be disposed.

In definitive, we are here creating a memory leak by using a context that will keep growing in size through the whole application lifetime

2. Easy solution

Once spotted, the leak is easy to fix: DBContext should have a short life span!

We have 2 solutions here, either configure the ORM to avoid tacking entities or manually reduce the context lifetime.

Our solution here is, for each loop, to request a new DBContext that will be disposed at the end of the current iteration.