A
A
artshelom2021-11-16 06:51:34
ASP.NET
artshelom, 2021-11-16 06:51:34

How to fix memory leak when working with EF?

Launched a service that runs in a cycle. But there was a problem that the amount of consumed memory is only growing.

while (!stoppingToken.IsCancellationRequested)
{
    var countPayments = db.Payments.Where(a => a.TypePayment == Data.Payments.TypePayment.Activity).Count();
    foreach (var payment in checkPayments)
    {
        var payment = db.Payments.Where(a => a.TypePayment == Data.Payments.TypePayment.Activity).OrderBy(a => a.Id).Skip(i)
            .Take(1).Include(a => a.Subscription).Include(a => a.Promocodes).FirstOrDefault();
        var telegramUser = db.TelegramUsers.Where(a => a.Id == payment.TelegramUserId).FirstOrDefault();

        if (payment == null || telegramUser == null)
            continue;

        try
        {
            CheckBlaBla(payment, telegramUser );
        }
        catch (Exception e)
        {
            throw e;
        }
        payment = null;
        telegramUser = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

Regular BackgroundService.
If I forcibly clean it like below, everything seems to be fine. But I don't understand a bit. Why, after the loss of links, they are not removed from memory (both in debugging and in release). What restrictions can be put in the config? Or is this the only way to deal with it?
payment = null;
telegramUser = null;
GC.Collect();
GC.WaitForPendingFinalizers();

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vasily Bannikov, 2021-11-16
@artshelom

1. The change tracker in EF eats up a lot of memory, so the first step is to turn it off by adding AsNoTracking to each request.
And where you really need to track changes - detach objects when they are not needed using Detach
2. Enable ServerGarbageCollection so that the garbage collector can work in several threads
3. Replace synchronous EF calls with asynchronous ones.
In theory, it should also help a little
4. We pull out objects from the database not one at a time, but in packs of 100 pieces, as it is easier for the GC to work with large pieces than with small ones
5. If I understand correctly, this is your HostedService.
In this case, look carefully at the use of the context, as the Change Tracker may be loaded elsewhere

A
Akylbek Omar, 2021-11-16
@Aboba45849894855

Documentation can be read here: Link

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question