PrismLibrary / Prism

Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
Other
6.37k stars 1.64k forks source link

[BUG][Android] BindingContext never cleared on Android after #3151 was merged causing vm's to memory leak #3186

Open skha83 opened 4 months ago

skha83 commented 4 months ago

Description

Ever since the changes in #3151 was merged to fix #3113 the BindingContext of views are never cleared on Android, because the Unloaded event is never triggered.

Steps to Reproduce

This can be reproduced by launching the E2E demo on the main branch on an Android device. Set a breakpoint here https://github.com/PrismLibrary/Prism/blob/90a701f0877daff0e6a55e2d527be11f4e2c2077/src/Maui/Prism.Maui/Common/MvvmHelpers.cs#L62 and here https://github.com/PrismLibrary/Prism/blob/90a701f0877daff0e6a55e2d527be11f4e2c2077/src/Maui/Prism.Maui/Common/MvvmHelpers.cs#L72

Navigate around in the app opening sub pages and close them again. An example could be:

  1. Go to Tabbed Page
  2. Navigate to Tab B
  3. Open View C page
  4. Navigate back to View B by pressing the back arrow in upper left corner.

The first breakpoint will get triggered correctly, but the 2nd breakpoint will never get triggered.

Because of this the ViewModels will never be garbage collected/Disposed. The Destroy method will of course be called if the ViewModel implements IDestructible. But if the ViewModel also implements IDisposable, the Dispose method will never be called. This happened before this change, whenever the BindingContext was cleared.

From the MAUI documentation it says that the Unloaded event "Occurs when an element is no longer connected to the main object tree." https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.visualelement.unloaded?view=net-maui-8.0 For some reason this event is never triggered whenever you close a sub page or navigate to another page which is not part of a navigation stack. I'm not sure who is responsible for removing the page so that it is no longer connected to the main object tree and this event will get triggered.

Platform with bug

.NET MAUI

Affected platforms

Android

Did you find any workaround?

I haven't found a workaround.

Relevant log output

No response

brianlagunas commented 1 month ago

The work around would be to implement IDestructible and clear the binding context yourself.

We are having trouble in this area because of how MAUI works. Before we would clear the binding context automatically, but that would happen too soon, and you would see a visual artifact as the Page was being removed from the view.

Also, please use a memory monitoring tool to verify the objects are being rooted, and which object is rooting them causing the memory leak. The most common mistake people make when they think they see a memory leak is by watching the memory increase in the task manager. That is not an indication of a memory leak.