question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Blazor Server Memory Leak

See original GitHub issue

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.
services.AddServerSideBlazor(o => {
    o.DisconnectedCircuitMaxRetained = 1;
    o.DisconnectedCircuitRetentionPeriod = TimeSpan.FromSeconds(10);
});
Data/WeatherForcastService.cs - Add variable forecast length.
public class WeatherForecastService
{
    // ...

    public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate, int count) // added `count` parameter
    {
        var rng = new Random();
        return Task.FromResult(Enumerable.Range(1, count).Select(index => new WeatherForecast
        { // ...
Pages/FetchData.razor - add controls for appending x amount of forecast rows.
else
{
    <span>Load</span>
    <input type="number" @bind="Count"/>
    <span>Items</span>
    <button @onclick="LoadMore">Go</button>

@* ... *@

@code {
    private List<WeatherForecast> Forecasts { get; set; } = new();
    private int Count { get; set; } = 5;
    private async Task LoadMore() => Forecasts
        .AddRange(await ForecastService.GetForecastAsync(DateTime.Now, Count));

    // ...
}

Steps

  1. Navigate to /fetchdata
  2. Load a large number of rows (e.g. 10,000)
  3. Navigate away from the page
  4. Repeat 1-3 until memory grows substantially (should jump ~ 25 MB / 10,000 rows).

image

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:
.NET SDK (reflecting any global.json):
 Version:   6.0.100-preview.3.21202.5
 Commit:    aee38a6dd4

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19043
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.100-preview.3.21202.5\

Host (useful for support):
  Version: 6.0.0-preview.3.21201.4
  Commit:  236cb21e3c

.NET SDKs installed:
  5.0.100 [C:\Program Files\dotnet\sdk]
  5.0.102 [C:\Program Files\dotnet\sdk]
  5.0.202 [C:\Program Files\dotnet\sdk]
  5.0.300-preview.21180.15 [C:\Program Files\dotnet\sdk]
  6.0.100-preview.3.21202.5 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.0-preview.3.21201.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.0-preview.3.21201.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.13 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.14 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.0-preview.3.21201.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

The IDE (VS / VS Code/ VS4Mac) you’re running on, and its version: Microsoft Visual Studio Community 2019, Version 16.9.4

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
SteveSandersonMScommented, May 12, 2021

Also as per another comment in #30210:

Blazor keeps a limited number of circuits in memory for up to 3 minutes (by default) to enable applications to reconnect to the same session in the event that there is an intermittent network connection.

… 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.

0reactions
davidfowlcommented, May 13, 2021

Is client GC the same thing as Workstation GC?

Yes

Yes, our application has a fair amount of concurrency.

What’s fair amount? 1000, 10000 concurrent users?

What does your hardware look like? RAM?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Severe blazor server memory leak · Issue #43221
Blazor server constantly allocates memory on every page refresh and does not return it. Garbage collection does not reduce memory usage at ...
Read more >
How to clean up memory in Blazor Server app when using ...
First, this is a default template memory usage snapshots. It's about what would be expected. I clicked around a bunch, opened and closed...
Read more >
Lifetimes and memory leaks
When we create a DotNetObjectReference , Blazor will generate a unique ID (integer for WASM, GUID for server side) and store a lookup...
Read more >
Why does Blazor server app takes away memory while ...
We developed a Blazor server app and is going through testing phase. Our clients have some concern. What we notice is that before...
Read more >
Blazor - Apparent memory leak : r/dotnet
Blazor Server allocates memory for every circuit and holds them for 3 minutes. Every time you are refreshing the page, the server is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found