-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
Description
We have a Blazor WebAssembly app whose memory keeps increasing until it hits the 2 GB limit, then silently crashes. We've narrowed down the main cause of the leak to compiled lambda expressions.
Reproduction Steps
The following code may be used to reproduce the memory leak. It can be wired up as the event handler of a button on a page. When left running in the active tab (in the foreground), it leaks around 46 MB of memory a minute, causing the 2 GB limit to be reached (and the app to crash) in 47 minutes.
private async Task RunMemoryLeakTestAsync()
{
long total = 0;
for (long i = 0; i < 2_000_000_000; i++)
{
Expression<Func<long, long>> expression = x => x + x;
var func = expression.Compile();
total += func(i);
if (i % 1_000 == 0)
await Task.Delay(millisecondsDelay: 100); // keep app responsive and give GC time to run
}
}
Expected behavior
The online consensus appears to be that compiled lambda expressions shouldn't cause memory leaks in .NET. (That answer was directed at .NET proper, not Blazor WebAssembly.)
Actual behavior
Compiled lambda expressions cause a memory leak in Blazor WebAssembly. The app would consequently silently crash once the 2 GB limit is reached.
Regression?
Compiled lambda expressions don't cause memory leaks in .NET proper.
Known Workarounds
The only workaround we have is to avoid using compiled lambda expressions in Blazor WebAssembly.
Configuration
Blazor WebAssembly, compiled on .NET 6.0 using Release configuration.
Run in Google Chrome 110.0.5481.104 (64-bit) without debugging, on Windows 10.
Other information
May be related to #62054. However, we've given our issue a quick test on .NET 7.0, and it still occurred.