Skip to content

[CollectionView] [Windows] memory leaks when ItemsSource has changed #13393

@ivan-todorov-progress

Description

@ivan-todorov-progress

Description

It seems that the CollectionView is leaking memory every time its ItemsSource property has changed.

Due to a lack of a proper memory profiler on all platforms, I am using a poor man's memory tracker implementation that stores a collection of WeakReferences and observes their IsAlive status:

public static class MemoryTracker
{
    private static readonly List<WeakReference> weakReferences = new List<WeakReference>();

    public static readonly BindableProperty IsTrackedProperty =
        BindableProperty.CreateAttached("IsTracked", typeof(bool), typeof(MemoryTracker),
            false, propertyChanged: OnIsTrackedChanged);

    public static int TotalObjectCount => weakReferences.Count;

    public static int AliveObjectCount => weakReferences.Count(weakReference => weakReference.IsAlive);

    public static bool GetIsTracked(BindableObject bindable)
    {
        return (bool)bindable.GetValue(IsTrackedProperty);
    }

    public static void SetIsTracked(BindableObject bindable, bool isTracked)
    {
        bindable.SetValue(IsTrackedProperty, isTracked);
    }

    private static void OnIsTrackedChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if ((bool)newValue)
        {
            var weakReference = new WeakReference(bindable);

            weakReferences.Add(weakReference);
        }
    }
}

I am using this class to track visual components in XAML like this:

<Grid local:MemoryTracker.IsTracked="True">
    <Label Text="{Binding}" />
</Grid>

I have prepared a small sample project that demonstrates the memory leak.

Note: It is possible that the following bug is related: Memory leaks EVERYWHERE. Since I am describing a somewhat different scenario, I have decided to log a separate bug report for it.

Steps to Reproduce

  1. Build and run the sample project in Release build configuration.
  2. Click on the "Refresh Memory Info" button to show the initial memory statistics.
  3. Click on the "Refresh Items Source" button several times to recreate the collection of items.
  4. Click on the "Refresh Memory Info" button to update the memory statistics.
  5. Repeat the steps 3 and 4 several times to observe how both total tracked objects and alive objects constantly grow.
  6. Click the Recreate Control button to recreate the CollectionView in the visual tree.
  7. Click on the "Refresh Memory Info" button to update the memory statistics.
  8. Observe how the alive objects are decreased after the CollectionView is recreated.

Note: Clicking the "Refresh Memory Info" button calls the garbage collector forcefully before updating the memory statistics:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

Link to public reproduction project repository

https://github.com/ivan-todorov-progress/maui-collection-view-memory-leak-bug

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

N/A

Did you find any workaround?

No response

Relevant log output

No response

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions