Radzen.sln demo project's memory leaks

Hello,

I downloaded the Radzen.sln demo project from https://github.com/radzenhq/radzen-blazor.

If I just run the demo project and I navigate through the application pages, in the Visual Studio diagnostic tools I see that the memory used is constantly increasing. It seams that there are resources that are never released.

Please, could you provide an example on how to use Radzen components to avoid this collateral effect?

Hi @Soraya,

We are not aware of any memory leaks. The growing memory will be collected at some point by the garbage collector - still if you find real memory leak you can send us pull request with fix.

Hi @enchev,

I don't know... I am in executing the demo application since 3 hours and the garbage collector has not been able to decrease the used memory yet, not even once.

Ok, I will try to understand if there is a real problem and if I will find and fix it I will share the solution with a pull request.

Bye,

The DataGrid IQueryable demo does leak memory. The leak is only for the lifetime of the Blazor component. I don't think it's a major problem, just something to be aware of.

The difference in scope between ASP.NET Core requests and Blazor circuits is well known. This affects how we use DbContext. Blazor tutorials for CRUD operations say to use an IDbContextFactory instead of retaining a DbContext. But this is no help when we want to use a DbSet as an IQueryable. Microsoft's own docs say you can scope a DbContext to a Blazor component. This is what the demos do. But doing this has consequences.

RadzenDataGrid is agnostic about EF Core. It doesn't know and can't do anything about the fact that using a DbSet as an IQueryable causes the DbContext to track (i.e., leak) a bunch of entities. To see this in action, stick this code in RadzenDataGrid.razor, right after @if (Data != null) in <tbody>:

var context = Data.GetType().GetField("_context", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(Data);
var tracker = context?.GetType().GetProperty("ChangeTracker")?.GetValue(context);
var entries = tracker?.GetType().GetMethod("Entries", 0, [])?.Invoke(tracker, []) as System.Collections.Generic.IEnumerable<object>;
if(entries == null)
{
    System.Diagnostics.Debug.WriteLine("Data is not a DbSet");
}
else
{
    System.Diagnostics.Debug.WriteLine($"tracked entities: {entries.Count()}");
}

When you first open the IQueryable demo, the DbContext is tracking 665 entities. But I think that's an artifact of initially populating the DbContext. If you navigate to another DataGrid demo and then back to IQueryable, you see the true scale of the leak. Initially the DbContext is tracking 5 entities, i.e., one page. When you navigate to the next page, it's tracking 9 entities. If there were more pages, the count would keep increasing until the user navigates to a different component. So how much this leak might affect you depends how your app is used.