I have an ASP.NET Core 3 website that is frequently running out of memory on Azure.
One of the heavy-lifting (but frequently used) functions is to generate reports. So I thought I'd use one such report as a test case to see what's going on.
Here is a memory snapshot after the application loads, and then after 9 subsequent requests for one of the reports.
Looking at the diagnostics, lots of memory is consumed by EF change tracking objects.
I've found that if I use options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); in startup, then the snapshots for the same activity produces the following:
This is a massive improvement - adding 2 MB for every request is not viable. Is this normal - I would have thought that even with change tracking on, the GC wouldn't let it get this bad? Or could there be something in my report code that is making it hold onto references or something - I read that static variables in a class can lead to the GC not freeing up those instances, is that a possibility? I'm not sure if switching off some default functionality is just a band-aid to something else I'm doing fundamentally wrong (I'm pretty sure I'm disposing everyting with using statements, etc.).




