Skip to content

[windows] fix VisualDiagnosticsOverlay keeping Page's alive#23489

Merged
jonathanpeppers merged 2 commits into
dotnet:mainfrom
jonathanpeppers:VisualDiagnosticsOverlayLeaks
Jul 10, 2024
Merged

[windows] fix VisualDiagnosticsOverlay keeping Page's alive#23489
jonathanpeppers merged 2 commits into
dotnet:mainfrom
jonathanpeppers:VisualDiagnosticsOverlayLeaks

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Fixes: #23034
Context: https://github.com/user-attachments/files/15817814/MauiApp1.zip

In the above sample app, you can observe a memory leak on Windows by doing:

Application.Current.MainPage = new Page1(); // This page lives forever
Application.Current.MainPage = new Page2();

Reviewing memory snapshots, it appears that the
VisualDiagnosticsOverlay class is keeping the Page1 instance alive:

MauiApp1.Page1
-> Microsoft.Maui.Platform.ContentPanel
    -> Microsoft.Maui.Controls.VisualDiagnostics.VisualDiagnosticsOverlay
        -> Microsoft.Maui.Controls.Window

In this case, the Window holds a reference to the VisualDiagnosticsOverlay, and the Window is still open. VisualDiagnosticsOverlay's base class is WindowOverlay, which has a _platformElement field holding the ContentPanel which holds the Page1 instance.

In this case, _platformElement is only used for unsubscribing events, so it feels like we can just change it to a WeakReference to solve the issue.

I was able to write a test for this scenario as well.

Fixes: dotnet#23034
Context: https://github.com/user-attachments/files/15817814/MauiApp1.zip

In the above sample app, you can observe a memory leak on Windows
by doing:

    Application.Current.MainPage = new Page1(); // This page lives forever
    Application.Current.MainPage = new Page2();

Reviewing memory snapshots, it appears that the
`VisualDiagnosticsOverlay` class is keeping the `Page1` instance
alive:

    MauiApp1.Page1
    -> Microsoft.Maui.Platform.ContentPanel
        -> Microsoft.Maui.Controls.VisualDiagnostics.VisualDiagnosticsOverlay
            -> Microsoft.Maui.Controls.Window

In this case, the `Window` holds a reference to the
`VisualDiagnosticsOverlay`, and the `Window` is still open.
`VisualDiagnosticsOverlay`'s base class is `WindowOverlay`, which
has a `_platformElement` field holding the `ContentPanel` which
holds the `Page1` instance.

In this case, `_platformElement` is only used for unsubscribing
events, so it feels like we can just change it to a `WeakReference`
to solve the issue.

I was able to write a test for this scenario as well.
@jonathanpeppers jonathanpeppers added platform/windows perf/memory-leak 💦 Memory usage grows / objects live forever (sub: perf) labels Jul 8, 2024
@jonathanpeppers

Copy link
Copy Markdown
Member Author

The iOS/Catalyst tests have a failure:

System.InvalidOperationException : MauiContext should have been set on parent.

Comment on lines +438 to +442
[Fact("VisualDiagnosticsOverlay Does Not Leak"
#if IOS || MACCATALYST
, Skip = "Fails with 'MauiContext should have been set on parent.'"
#endif
)]

@jonathanpeppers jonathanpeppers Jul 9, 2024

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not figure out how to get this test to work on iOS/Catalyst. It seems like it wants the Window's Handler to be created for it to work.

In either case, I think there is only a problem on Windows here.

@jonathanpeppers jonathanpeppers marked this pull request as ready for review July 9, 2024 21:29
@jonathanpeppers jonathanpeppers requested a review from a team as a code owner July 9, 2024 21:29
@jonathanpeppers jonathanpeppers merged commit 191262d into dotnet:main Jul 10, 2024
@jonathanpeppers jonathanpeppers deleted the VisualDiagnosticsOverlayLeaks branch July 10, 2024 21:58
@samhouts samhouts added fixed-in-net9.0-nightly This may be available in a nightly release! fixed-in-net8.0-nightly This may be available in a nightly release! fixed-in-8.0.80 and removed fixed-in-net9.0-nightly This may be available in a nightly release! fixed-in-net8.0-nightly This may be available in a nightly release! labels Aug 2, 2024
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

fixed-in-8.0.80 fixed-in-net9.0-nightly This may be available in a nightly release! perf/memory-leak 💦 Memory usage grows / objects live forever (sub: perf) platform/windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory leaks when replacing Application.Current.MainPage by a new one keep the old page in memory

3 participants