Memory leak on Entity framework during HangfireJobs

Hello,
our client has implementation of current version of hangfire in .net core 2.1. Client has several type of jobs. Some of them are long (couple of minutes). What client is observing is that, after each cycle od processing couple of hundred or thousand of jobs, memory is increasing. We’ve suggested client switching GC from WorkSpace to Server (before with memory leak there was corresponding CPU leak). After this switch memory is increasing less and cpu went back to normal values.

We’ve done memory dump and we see that most of memory is allocated by Entity framework. It looks like that:

root - Caching.Memory.CacheEntry
DatabaseContext
Entity framework

Client is creating context in job class and it’s passed through several subclasses and loops. It looks like this may be issue because application has some problems with disposing context. They don’t observe any issues related to disposing (method is executing fine at the end of job). Do you have any experience with such cases? I’m wondering if moving cache creation inside the loop may help here.

Regards.
Sebastian Krystosik

@skrystosik have you managed to resolve the issue? we are experiencing the same issue and we think moving to Core 2.1 to 3.1 or 5 might solve this.

I’m facing the same issue.

Additional info:
a. Running a Windows Service in .net 6 that starts a Hangfire Server to handle jobs of five queues.

b. Hangfire.Core and Hangfire.SqlServer version 1.7.28

c. Command AddDbContext
services.AddDbContext(options =>
{
options.UseSqlServer(Configuration.GetConnectionString(“myConnStr”), builder =>
{
builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
});
}, ServiceLifetime.Transient);

The issue:
The application creates many instances of ApplicationDBContext class for each executed job (it’s ok, because ApplicationDBContext is referenced in repositories classes used to process the jobs). But, after job completion these objects aren’t deallocated, significantly increasing the use of memory and the ammout of ApplicationDBContext instances. When another job starts executing, more ApplicationDBContext are allocated to them.

As result, the service stop working or consume all the server memory.

Workaround:
Changed WorkerCount = 1 in BackgroundJobServerOptions and services.AddDbContext from ServiceLifetime.Transient to ServiceLifetime.Scoped

Now, it allocates just one ApplicationDBContext, but running only one job at once, decreasing the solution performance.

Note: I can’t just keep WorkerCount > 1 and services.AddDbContext = ServiceLifetime.Transient because some jobs share access the same repositories, causing DBContext state change concurrence errors.