-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[UWP] CollectionView Memory Leak #14780
[UWP] CollectionView Memory Leak #14780
Conversation
{ | ||
// Stop tracking the old layout | ||
Layout.PropertyChanged -= LayoutPropertyChanged; | ||
oldStructuredItemsView.ItemsLayout.PropertyChanged -= LayoutPropertyChanged; | ||
oldStructuredItemsView.ItemsLayout = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this null
assignment, but if we don't do it, the memory leak persists.
I also tried calling SetInheritedBindingContext(oldStructuredItemsView.ItemsLayout, null)
instead, without success.
@jsuarezruiz maybe you have an idea or can validate that this should not produce side effects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Yann! Sorry I only got to this now. I will try and think how we can validate this. I assume you tested this yourself? Are you using this code now in any of your apps by any chance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Gerald, I use the simple project available here with VS Diagnostics Tools to reproduce/check the fix.
For the moment, on production we use an extended renderer as workaround on many apps. Not exactly the same code, because there are private/internal on the base renderer, but the result is the same:
public class ExtendedCollectionViewRenderer : Xamarin.Forms.Platform.UWP.CollectionViewRenderer
{
protected override void Dispose(bool disposing)
{
base.TearDownOldElement(Element);
if (Element.ItemsLayout is LinearItemsLayout linearItemsLayout)
{
Element.ItemsLayout = new LinearItemsLayout(linearItemsLayout.Orientation);
}
else if (Element.ItemsLayout is GridItemsLayout gridItemsLayout)
{
Element.ItemsLayout = new GridItemsLayout(gridItemsLayout.Span, gridItemsLayout.Orientation);
}
else
{
Element.ItemsLayout = null;
}
base.Dispose(disposing);
}
protected override void CleanUpCollectionViewSource()
{
var itemContentControls = ListViewBase.GetChildren<ItemContentControl>();
foreach (var itemContentControl in itemContentControls)
{
itemContentControl.FormsDataContext = null;
itemContentControl.DataContext = null;
}
base.CleanUpCollectionViewSource();
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the build completes there should be NuGets produced, would you maybe be able to try them out on projects where you have this problem and see if this works as expected and doesn't break anything else? The instructions can be found here. That would be very helpful, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did some tests with the nuget produced on an application with multiple CollectionView
on different views, the Memory Leak is solved.
By the way, I also updated the test project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the cooperation @YZahringer !
/azp run |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Azure Pipelines successfully started running 1 pipeline(s). |
Description of Change
Unsubscribe from
oldElement
onTearDownOldElement
instead of currentLayout/ItemsView
that is already null.Issues Resolved
API Changes
None
Platforms Affected
Behavioral/Visual Changes
None
Before/After Screenshots
Not applicable
Testing Procedure
Case 1: Nav back from CollectionView
Memory Snapshot
CollectionView
Memory Snapshot
and compare it with the first oneCollectionView
, BindingContext VM, Items VM are releasedCase 2: Change ItemsSource of CollectionView
Memory Snapshot
CollectionView
ItemsSource
with an empty collectionMemory Snapshot
and compare it with the first oneSimple project available here: https://github.com/MADSENSE/Madsense.XamarinForms.Sample/tree/collectionview-memory-leak
PR Checklist