Skip to content

[ios] fix memory leak in Frame, VisualElementRenderer#18552

Merged
jonathanpeppers merged 1 commit intodotnet:mainfrom
jonathanpeppers:VisualElementRendererLeaks
Nov 13, 2023
Merged

[ios] fix memory leak in Frame, VisualElementRenderer#18552
jonathanpeppers merged 1 commit intodotnet:mainfrom
jonathanpeppers:VisualElementRendererLeaks

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Member

Context: #18365

I could reproduce a leak in Frame by adding a parameterized test:

[InlineData(typeof(Frame))]
public async Task HandlerDoesNotLeak(Type type)

FrameRenderer has a circular reference via its base type, VisualElementRenderer:

  • Frame ->
  • FrameRenderer / VisualElementRenderer ->
  • Frame (via VisualElementRenderer._virtualView)

To solve this issue, I made _virtualView a WeakReference, but only on iOS or MacCatalyst platforms. We don't necessarily need this treatment for Windows or Android.

My initial attempt threw a NullReferenceException, because the Element property is accessed before SetVirtualView() returns. I had to create a _tempElement field to hold the value temporarily, clearing it to avoid a circular reference.

The Roslyn analyzer didn't catch this cycle because it doesn't warn about IPlatformViewHandler, only NSObject's. Will investigate further on this example here:

jonathanpeppers/memory-analyzers#12

Context: dotnet#18365

I could reproduce a leak in `Frame` by adding a parameterized test:

    [InlineData(typeof(Frame))]
    public async Task HandlerDoesNotLeak(Type type)

`FrameRenderer` has a circular reference via its base type,
`VisualElementRenderer`:

* `Frame` ->
* `FrameRenderer` / `VisualElementRenderer` ->
* `Frame` (via `VisualElementRenderer._virtualView`)

To solve this issue, I made `_virtualView` a `WeakReference`, but only
on iOS or MacCatalyst platforms. We don't necessarily need this
treatment for Windows or Android.

My initial attempt threw a `NullReferenceException`, because the
`Element` property is accessed before `SetVirtualView()` returns. I
had to create a `_tempElement` field to hold the value temporarily,
clearing it to avoid a circular reference.

The Roslyn analyzer didn't catch this cycle because it doesn't warn
about `IPlatformViewHandler`, only `NSObject`'s. Will investigate
further on this example here:

jonathanpeppers/memory-analyzers#12
@jonathanpeppers jonathanpeppers added this to the .NET 8 + Servicing milestone Nov 6, 2023
@jonathanpeppers jonathanpeppers marked this pull request as ready for review November 7, 2023 02:57
@jonathanpeppers jonathanpeppers requested a review from a team as a code owner November 7, 2023 02:57
@jonathanpeppers jonathanpeppers added perf/memory-leak 💦 Memory usage grows / objects live forever (sub: perf) platform/ios labels Nov 7, 2023
@Eilon Eilon added the legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor label Nov 9, 2023
@jonathanpeppers jonathanpeppers merged commit 8bc2a2f into dotnet:main Nov 13, 2023
@jonathanpeppers jonathanpeppers deleted the VisualElementRendererLeaks branch November 13, 2023 19:58
@github-actions github-actions bot locked and limited conversation to collaborators Dec 14, 2023
@Eilon Eilon added area-controls-frame Frame and removed legacy-area-controls Label, Button, CheckBox, Slider, Stepper, Switch, Picker, Entry, Editor labels May 13, 2024
@samhouts samhouts added the fixed-in-8.0.6 Look for this fix in 8.0.6 SR1! label Aug 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-frame Frame fixed-in-8.0.6 Look for this fix in 8.0.6 SR1! perf/memory-leak 💦 Memory usage grows / objects live forever (sub: perf) platform/ios

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants