Search code examples
c#blazorblazor-server-sidevisual-studio-2022

How to clean up memory in Blazor Server app when using navigates away from a page


I am working to resolve why my Blazor App seems to eat memory until the application pool is forced to recycle due to 4 gigs of memory being used.

First, this is a default template memory usage snapshots. It's about what would be expected. I clicked around a bunch, opened and closed the page multiple times, and the memory usage is stable.

Default Blazor Template Memory Usage

This is the Customer Service App. I start the app on the empty home page, then go to Page1. Then I take snap shot, and go back to the home page, then back to Page1. Each time I so this, the memory gets higher and higher.

This is what the object list looks like. It's not clear to me what the issue is. Is there cleanup I should be doing when the user navigates away from a page to ensure that the memory is cleaned up?

When this app is published to the network IIS machine, it eats up memory until the limit of 4 gigs is reached. This occurs with only 1 or two people using the app at a time. So there must be some sort of memory issue to be resolved. The app itself is running fine, it's just the memory issue I am trying to resolve.

enter image description here


Solution

  • Since this question now has over a thousand view, I am going to post a response here on this.

    First, make sure you have IDisposable on your pages.

    Second, there was no single issue that I found that resolved the issue. The issue was resolved, and it now works as expected, but it took serious digging to find the issues. I just used the Visual Studio memory tools and looked for objects that were not getting released as expected. A blazor server app runs heavily on the server, and if there are references that are not getting released, it holds the object in memory and you have a memory leak.

    While I always assumed memory leaks were a thing of the past with .net, it clearly was not the case.

    So make sure you are careful with all object references and make them all as narrow (localized) as possible, especially anything dealing with Entity Framework like context. Read the docs on how a context should be used and disposed as frequently as possible.

    Hope this helps, that's all I got.

    UPDATE #2: I had a chance to work with a client who had a simliar issue: Memory would increase and increase without it ever being released as expected. The workaround was to increase the server memory. Here is what we came up with to address this:

    1. If you are on IIS, set the AppPool to recycle one time each day, say during off hours. IIS comes with a default setting but it is good practice to se it to once each 24 hours. This will clean up any unclaimed memory.

    2. Seach your code for the use of events. Seach for "+=". This pages must use @implments IDisposible In the Dispose event, use "-=" to unregister the event.

    3. If you have a page that uses an unusually large amount of memory (for example, getting a very large data set) consider implementing IDisposable and nulling out all of your data collections during the disposal. While this may not strictly be required, I suspect that this memory may be cached in the circuit if it should be "refreshed" and the memory not released until the circuit is released. The default time for a circuit to be released is 3 minutes, but this setting can be changed. Thus you could have a circuit which is waiting for a reconnection which has a large amount of memory usage. I don't really know if IDisposable gets called in those circumstances, but it's worth considering if you cannot find the source of your memory leak.

    I am no memory guru, just field observations which has worked for me.