Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[controls] fix memory leak with Grid Row/ColumnDefinitions
Context: dotnet#15860 In a customer's app, they have the setup: <!-- Resources/Styles/Styles.xaml --> <Style TargetType="Grid" x:Key="GridStyleWithColumnDefinitions"> <Setter Property="ColumnDefinitions" Value="18,*"/> </Style> Then a page with: <Grid Style="{StaticResource GridStyleWithColumnDefinitions}" /> Navigating forward & back from this page would show that the entire `Page` would live forever! What is interesting, is simply removing the Grid's `Style` solved the problem?!? I narrowed this down to a unit test: [Fact] public async Task ColumnDefinitionDoesNotLeak() { // Long-lived column, like from a Style in App.Resources var column = new ColumnDefinition(); WeakReference reference; { var grid = new Grid(); grid.ColumnDefinitions.Add(column); reference = new(grid); } await Task.Yield(); GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(reference.IsAlive, "Grid should not be alive!"); } https://github.com/dotnet/maui/blob/cda3eb3381cfb686567ed05e3eb8e8f26c02d785/src/Controls/src/Core/Layout/Grid.cs#L20 `Grid` subscribes to `DefinitionCollection<T>.ItemSizeChanged`, and in this case the `DefinitionCollection<T>` lived indefinitely in an application-wide `ResourceDictionary`. The simplest solution is to make the `ItemSizeChanged` event use `WeakEventManager` as was done for other events like `Application.RequestedThemeChanged`: https://github.com/dotnet/maui/blob/cda3eb3381cfb686567ed05e3eb8e8f26c02d785/src/Controls/src/Core/Application/Application.cs#L221-L225 Since MAUI owns the property, we can use the simple solution here. This is one issue solved in the customer app, but I will need to retest the app in dotnet#15860 to see if there are further issues.
- Loading branch information