BlazorServer doesn't release circuits/component instances after 25mins+forced GC2
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Describe the bug
Blazor component instances and circuit objects/instances don’t seem to be released from memory after 25+ minutes and forced 2nd generation garbage collection using the basic out of the box Blazor Server template. I tried to follow the recommendations from @javiercn in this post https://github.com/dotnet/aspnetcore/issues/30210#issuecomment-779849309 to test this.
Expected Behavior
The amount of Counter instances & Circuits should go to zero after 10/20/30 minutes and a forced garbage collection ( GC.Collect(2, GCCollectionMode.Forced);).
Steps To Reproduce
- Create a default Blazor Server template app in Visual Studio 17.4.0 Preview 2.
- Go to the Counter.razor component and change the method to
private void IncrementCount() { GC.Collect(2, GCCollectionMode.Forced); }
as recommended by @javiercn here https://github.com/dotnet/aspnetcore/issues/30210#issuecomment-779849309 so we can force a GC collect after 20 minutes.
- Set the build mode to *Release
- Execute the application
- Click on the Counter tab button so we navigate to the counter page.
- Now on the counter page, press F5 (refresh page) 10 times.
- Open the Diagnostics Tool in VS and take a memory snapshot.
- Search in the snapshot for *Counter and *Circuits.circuit
and
So you can see there’re 11 instances (1 initial request + 10 refreshes) of the component as expected in memory, and the related circuits.
-
Wait 10 minutes.
-
Take a new snapshot.
Component instances & circuits still there after 10 minutes.
-
Wait another 10 minutes (just in case)
-
Take a new snapshot
- So we waited 20 minutes (the double recommended by javier), all the instances are still there… So now let’s trigger a forced GC collect using the Counter button for which we changed the code:
We can see a GC has occured.
- Take another snapshot to see if after 25+ minutes and a forced GC, Counter components & circuit instances have been released.
So nothing has changed, 11 instances are still there after almost an hour, and a forced GC collection.
Just in case I forced GC a couple more times.
Still nothing is released.
Exceptions (if any)
No response
.NET Version
7.0.100-rc.1.22431.12
Anything else?
What I’ve tried to see if this gets fixed:
builder.Services.AddServerSideBlazor(options => {
options.DisconnectedCircuitMaxRetained = 0;
options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromSeconds(0);
});
-
Changing the GC mode to Workstation.
-
Debug & Release modes.
-
Closed the browser completely (but left the server running).
Nothing seems to make .NET to release Counter component instances & circuits after half an hour.
Issue Analytics
- State:
- Created a year ago
- Comments:7 (2 by maintainers)
You’re welcome! Blazor is great!
Is this behaviour which has arisen in 7.0 because of new STJ caching JsonSerializerOptions? It does seem a bit unexpected that serializer options would become a root for potentially large/numerous application data structures.
Whoever carefully used WeakReference<> on that cache to prevent it blocking GC must feel particularly galled that someone’s already found a way to trap huge amounts of data via the cache key… 😃