I'm seeing my memory usage getting too hign on Diagnostic Tools after I call some endpoints.
I tried to isolate the problem in the smallest chunk I could, so I could eliminate all other factors, and I ended up with the following:
[HttpGet("test")]
public ActionResult Test()
{
var results = _context.Products
.Include(x => x.Images)
.Include(x => x.Options)
.ThenInclude(x => x.Lists)
.ThenInclude(x => x.PriceChangeRule)
.Include(x => x.Options)
.ThenInclude(x => x.Lists)
.ThenInclude(x => x.Items)
.ThenInclude(x => x.PriceChangeRule)
.Include(x => x.Options)
.ThenInclude(x => x.Lists)
.ThenInclude(x => x.Items)
.ThenInclude(x => x.SupplierFinishingItem)
.ThenInclude(x => x.Parent)
.Include(x => x.Category)
.ThenInclude(x => x.PriceFormation)
.ThenInclude(x => x.Rules)
.Include(x => x.Supplier)
.ThenInclude(x => x.PriceFormation)
.ThenInclude(x => x.Rules)
.Include(x => x.PriceFormation)
.ThenInclude(x => x.Rules)
.AsNoTracking().ToList();
return Ok(_mapper.Map<List<AbstractProductListItemDto>>(results));
}
It is a big query, with lots of includes, but the amount of data returned from the database is not huge, it's ~10.000 items. When I serialize this result it has only 3.5Mb.
My API is using around 300Mb of memory, then when I call this test endpoint, this value goes to about 1.2Gb. I think this is too much for only 3.5Mb of data, but I don't know how EF Core works internally, so I'll just ignore it.
My problem is that, as far as I understand, the DbContext is added as a scoped service, so it's created when the request starts and then killed when it finishes. Here's how I'm registering it:
services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
If my understanding is correct, when the request is finished, that huge amount of memory should be disposed, right?
The problem is that my memory usage never goes back again, I tried disposing the context manually, calling the garbage collector manually too, but the memory stays at 1.2Gb.
Am I missing something here?
.AsNoTracking()?