-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
I have a Customer Service app which is used by about 10 staff. It is a .net 6 Blazor Server app. It uses EF Core 6 to retrieve and update data from Sql Server.
The app runs as expected as far as the end user is concerned.. However, what is unexpected is the memory usage on the server. The memory usage continually climbs until about 4 gigs of memory is used by the Application Pool at which point it is automatically recycled due to the settings on IIS for memory usage. In production, this recycling occurs about every two hours throughout the day. (Initially, this setting was not set, and it ate all the memory of the server until the server started throwing out of memory exceptions.)
The question is whether this is expected behavior or not. I have used the Diagnostic Tools in VS22 to see what is happening with the memory. The memory grows each time a page is accessed within the application. If the user stays on the same page, the memory stays level. But if that page is left, and then the user comes back to the page again, the memory raises, never to come back down again.
When the page is initialized, there are various lookup lists that are populated. For example, there is a list of Contacts with about 75 items. If I go to this page, and then take a memory snapshot, then I can see the count at 75 Contacts. If I then leave the page and go to a different page, and then come back again, the same list is again retrieved from the database, and in memory, there are now 150. The count grows every time the page is accessed.
It seems to me that the GC would be collecting these no longer used Contacts. But even if a force a GC with GC.Collect(), there is no reduction in the number of items.
So is this expected behavior? If not, what should I be doing to clean up these resources?
One thing I have found to help is that if I clear the Collection in the Dispose() method of the page, then these objects do NOT show up in the Heap, and after a GC, the memory is reclaimed.
For example, after going to the page 20 times without using List.Clear(), the heap size even after a GC is 41 Megs.
Using List.Clear() in the dispose() for 20 page views results in the heap size of 41, but after GC, it drops down to 23 Megs. So clearly this is beneficial. But as I understand garbage collection, the object which are no longer used in a page should be automatically cleaned up. Is this concept incorrect?