-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ios] fix memory leak in Image #15062
Conversation
c1e580f
to
1643aba
Compare
2367013
to
878e6cf
Compare
This does not fully solve: #14664 It appears there are other cycles in the customer sample: Here is one of them: maui/src/Controls/src/Core/Platform/GestureManager/GestureManager.cs Lines 15 to 18 in c3f269c
We can merge this one as a starting place, and maybe adding the views to the screen in my test would trigger more issues? |
@@ -7,18 +7,34 @@ namespace Microsoft.Maui.Platform | |||
{ | |||
public class MauiImageView : UIImageView | |||
{ | |||
WeakReference<ImageHandler>? _handler; |
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.
Maybe this can be a public property? This way we don't have to change API at all much - the event still works - we just don't use it? Sort of like the iOS bending of a weak delegate OR an event? We can still use the existing iOS constructors.
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.
We can mark the bad one as obsolete just to let people know why - and us. Rather than just "it will be removed", maybe we can be "Use Handler instead. iOS platform views should not have strong references to handlers or cross-platform views."
{ | ||
if (_handler is not null && _handler.TryGetTarget(out var handler)) | ||
{ | ||
handler.NotifyWindowChanged(); |
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 am not 100% happy with views reaching out into internal handlers as this means this view will never work for anything else, but for now maybe it is fine? The method of catching the iOS window change is not great and is a bit iffy - we could actually do all this in cross platform code. We now have a Window property. But this is more for another issue.
@PureWeen thoughts?
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.
If we made this one public on IImageHandler
and gave it a proper name, it would mean other IImageHandler
could work?
d8af8fe
to
ab79dd5
Compare
/rebase |
Context: dotnet#14664 (comment) `Image` has two different "cycles" on iOS: * `ImageHandler` -> `MauiImageView` -> `ImageHandler` * via the `WindowChanged` event * `ImageHandler` -> `ImageSourcePartLoader` -> `ImageHandler` * via `Handler`, `Func<IImageSourcePart?>`, and `Action<PlatformImage?>` This causes any `MauiImageView` to live forever. To solve these issues: * Get rid of the `MauiImageView.WindowChanged` event, and use a `WeakReference` to the handler instead. * `ImageSourcePartLoader` now only has a `WeakReference` to the handler. * This requires a new `ISetImageHandler` interface to be used by several handler types involving images. Hopefully the changes here are using `[Obsolete]` correctly to make things backwards compatible & less breaking changes. Unsure yet if this fully solves dotnet#14664, but at least one part of it.
Co-authored-by: Matthew Leibowitz <mattleibow@live.com>
ab79dd5
to
1480730
Compare
PlatformView.Image = obj; | ||
|
||
void OnWindowChanged(object? sender, EventArgs e) | ||
public void OnWindowChanged() |
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.
Do we want this to be a public API ? doesn't seem consistent with other Handlers
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.
My only comment is related with WindowChanged not sure if we want that public.
If it isn't public, then no one can implement But, let me know what to do to get this merged. |
* [ios] fix memory leak in Image Context: #14664 (comment) `Image` has two different "cycles" on iOS: * `ImageHandler` -> `MauiImageView` -> `ImageHandler` * via the `WindowChanged` event * `ImageHandler` -> `ImageSourcePartLoader` -> `ImageHandler` * via `Handler`, `Func<IImageSourcePart?>`, and `Action<PlatformImage?>` This causes any `MauiImageView` to live forever. To solve these issues: * Get rid of the `MauiImageView.WindowChanged` event, and use a `WeakReference` to the handler instead. * `ImageSourcePartLoader` now only has a `WeakReference` to the handler. * This requires a new `ISetImageHandler` interface to be used by several handler types involving images. Hopefully the changes here are using `[Obsolete]` correctly to make things backwards compatible & less breaking changes. Unsure yet if this fully solves #14664, but at least one part of it. * Update src/Core/src/Platform/ImageSourcePartLoader.cs Co-authored-by: Matthew Leibowitz <mattleibow@live.com> * Update MauiImageView.cs * Update MauiImageView.cs * ISetImageHandler -> IImageSourcePartSetter * IImageHandler.OnWindowChanged() is now public * Fix IImageSourcePartSetter namespace * MauiImageView._handler can be readonly --------- Co-authored-by: Matthew Leibowitz <mattleibow@live.com>
There are currently a number of PRs that are all working together to fix the memory leak issues on iOS. Any of these PRs backported individually will most likely not fix the issues that users are currently seeing. We have a few reproductions that we are testing against where we still haven't quite fixed all of the memory leaks. Backporting this PR would most likely have a higher chance of causing regressions (38 files changed) than it would actually fixing the overall problem. .NET8 is now part of VS so if you can verify your scenarios against .NET8 that will ensure we've fixed as many leaks as possible for .NET8. If there are still leaks that users are finding in .NET8 after the release of .NET8 those will have a decent chance of being backported. We should be through the larger sets of changes by the time we hit .NET8 so post .NET8 changes should be smaller/safer. |
Context: #14664 (comment)
Image
has two different "cycles" on iOS:ImageHandler
->MauiImageView
->ImageHandler
WindowChanged
eventImageHandler
->ImageSourcePartLoader
->ImageHandler
Handler
,Func<IImageSourcePart?>
, andAction<PlatformImage?>
This causes any
MauiImageView
to live forever.To solve these issues:
Get rid of the
MauiImageView.WindowChanged
event, and use aWeakReference
to the handler instead.ImageSourcePartLoader
now only has aWeakReference
to the handler.This requires a new
ISetImageHandler
interface to be used by several handler types involving images.Hopefully the changes here are using
[Obsolete]
correctly to make things backwards compatible & less breaking changes.Unsure yet if this fully solves #14664, but at least one part of it.