-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
fix(Win32): PopupImpl memory leak #16890
fix(Win32): PopupImpl memory leak #16890
Conversation
You can test this PR using the following package version. |
src/Avalonia.Controls/TopLevel.cs
Outdated
{ | ||
onValue(GetValue(property)); |
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 don't quite see the point of altering the callback signature. It's only possible to call CreatePlatformImplBinding
from the same object instance, and any callbacks would be referencing this
rather than the PlatformImpl
value captured during callback creation.
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.
The closure creates a cross reference that does not allow the PopupImpl to be collected
To test
- Apply Sandbox Patch SandBox-Test-Patch.patch
- Build Sandbox in Release mode
- Run dotMemoery
- Make memory Snapshot (Snapshot 1)
- Click on Button e
- Dismiss popup with click on window
- Repeat steps 5, 6 ten times.
- Make memory Snapshot (Snapshot 2)
- Force GC Collect
- Make memory Snapshot (Snapshot 3)
- Kill Sandbox
- Compare Snapshot 2 and 3
- Filter for
PopupImp
- You can see there is only
ManagedPopupPositionerPopupImplHelper+<>c
- Revert some change with:
git checkout 7041139ee0556c474dad7dc599c0b69bcdf5d1b7~ -- "src/Avalonia.Controls/WindowBase.cs" git checkout 7041139ee0556c474dad7dc599c0b69bcdf5d1b7~ -- "src/Avalonia.Controls/Window.cs" git checkout 7041139ee0556c474dad7dc599c0b69bcdf5d1b7~ -- "src/Avalonia.Controls/TopLevel.cs"
- Repeat steps from 2 to 13
- In in the list besides ManagedPopupPositionerPopupImplHelper there is a PopupImpl instance
- If you step into you can see that retained from
Avalonia.Controls.TopLevel+<>c__DisplayClass33_0.impl
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.
It's the closure that's passed to CompositionTarget, not the one related to CreatePlatformImplBinding
. The closures passed to CreatePlatformImplBinding
are consuming PlatformImpl
property and are capturing this
.
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.
BTW, the leak itself is about keeping a reference to a disposed PopupRoot, rather than about TopLevel keeping references to its internals after being disposed.
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.
So I revert TopLevel except for line 222?
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.
You can replace line 222 with Renderer = new CompositingRenderer(this, impl.Compositor, () => PlatformImpl.Surfaces ?? []);
, it will capture this
and use the property. The rest of the TopLevel changes seems to be not needed.
You can test this PR using the following package version. |
Do I need to make any other changes? |
_inputPane?.Dispose(); | ||
_inputPane = 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.
We already dispose pane on WM_DESTROY. And it should be guaranteed to be called unless process was terminated (in which case we don't care about disposing).
_inputPane?.Dispose(); |
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.
Other than that lgtm
You can test this PR using the following package version. |
You can test this PR using the following package version. |
What does the pull request do?
Fix memory leak when OverlayPopups is false and popup opens, PopupImpl is not released when popup closes.
What is the current behavior?
PopupImpl is not released when popup closes.
What is the updated/expected behavior with this PR?
How was the solution implemented (if it's not obvious)?
TopLevel
,WindowBase
andWindow
that retention PopupImplAvalonia.Win32/WindowImpl
andWindowsInputPane
Checklist
Breaking changes
Obsoletions / Deprecations
Fixed issues