-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blazor Server Memory Leak #32588
Comments
Per #30210 suggestions, I added a |
The garbage collector triggers collections when you allocate. What behavior are you looking for? You can configure GC limits https://docs.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector You might also consider taking a GC trace and sharing it ( |
Also as per another comment in #30210:
... you would need to wait 3 minutes before triggering the collection in order for an abandoned circuit's data to be released. Please see DisconnectedCircuitRetentionPeriod if you want to change the config for this. |
...There should really be an undo button for that. services.AddServerSideBlazor(o => {
o.DisconnectedCircuitMaxRetained = 1;
o.DisconnectedCircuitRetentionPeriod = TimeSpan.FromSeconds(10);
}); |
Thanks for clarifying. I didn't spot that within the collapsed code blocks. I'd say the main two ways for trying to diagnose what's going on would be:
|
I took a (dotnet) trace recording events incurring memory and the forced |
I tried what Steve suggested and attempted to create an out-of-memory condition. The app consistently gc'd 1-2 GB when the memory total reached ~3.5GB, so no memory leak. I understand that this is a stateful application and will consume more memory than a stateless web API, for example. I am wondering if there is any reason GC can't occur more often? With enough time, I can get our production app to consume 2+ GB of memory for a single user under normal usage, which does not seem very scalable. Unlike the example app, we are putting limits on list lengths, pagination, etc. Is this something I can configure in the GC limits? |
The GC doesn't work that way, it doesn't run on a timer. It runs based on what you allocate. When you have memory hanging around but no allocations it won't do anything until one of the thresholds are reached, not even with enough time.
It might make more sense to use client GC rather than server GC here. It should scale fine but it is pretty lazy to collect. For these scenarios though, that may not make as much sense. Does you application have lots of concurrency? |
Is client GC the same thing as Workstation GC? Yes, our application has a fair amount of concurrency. |
Yes
What's fair amount? 1000, 10000 concurrent users? What does your hardware look like? RAM? |
Describe the bug
Old data isn't cleared from memory, regardless of time passage and
CircutOptions
configuration.To Reproduce
Project
Repository Link
I've experienced this in a production app, but I have recreated the behavior using the default blazor server template. I made the following changes:
Startup.cs - reduce retained connections.
Data/WeatherForcastService.cs - Add variable forecast length.
Pages/FetchData.razor - add controls for appending
x
amount of forecast rows.Steps
Memory is never released at this point, regardless of time passed or page closed/reloaded. Even if it was, why does memory grow this way? I would expect it to release memory when I navigate away because that data is never accessed after that point.
Exceptions (if any)
n/a
Further technical details
ASP.NET Core version: net5.0
Include the output of
dotnet --info
:The IDE (VS / VS Code/ VS4Mac) you're running on, and its version: Microsoft Visual Studio Community 2019, Version 16.9.4
The text was updated successfully, but these errors were encountered: