Ensures cleanup of window event handlers - #11734
Open
Morten Nielsen (dotMorten) wants to merge 2 commits into
Open
Ensures cleanup of window event handlers#11734Morten Nielsen (dotMorten) wants to merge 2 commits into
Morten Nielsen (dotMorten) wants to merge 2 commits into
Conversation
This avoids a memory leak caused by listening to Window events, either from user-code or generated core from x:bind which will subscribe to the activated event.
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
Author
|
/azp run |
|
Azure Pipelines: 1 pipeline(s) were filtered out due to trigger conditions. |
Mike Crider (codendone)
approved these changes
Aug 31, 2026
Contributor
Author
|
/azp run |
|
Azure Pipelines: 1 pipeline(s) were filtered out due to trigger conditions. |
Hemant Kumar (Hemantxk)
approved these changes
Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This avoids a memory leak caused by listening to Window events, either from user-code or generated code from
x:bindwhich will subscribe to the activated event.Fixes
Fixes #7282 and #9960
PR Type
Description
Current Behavior
A closed desktop
Windowcan remain alive when one of its events has a managed handler.For example, an instance handling its own
Closedevent creates this retention chain:DesktopWindowImplstores handlers forActivated,Closed,SizeChanged, andVisibilityChangedinCFTMEventSource. Each handler is registered in the COM Global Interface Table. These registrations remain after the window closes and are normally revoked only when the event source is destroyed.When a handler references the Window, this creates a cycle: the GIT registration keeps the managed callback and Window alive, which prevents
DesktopWindowImpland its event sources from being destroyed.The issue also affects generated
{x:Bind}code as reported in #7282. Bindings declared on a Window generate anActivatedsubscription similar to:The generated bindings object references its Window through
dataRoot, so this subscription can retain the Window and its object graph after close.Applications can work around the issue by manually unsubscribing from every Window event, but that should not be required after the Window has permanently closed.
New Behavior
After a desktop Window closes successfully, WinUI clears its
Activated,Closed,SizeChanged, andVisibilityChangedevent sources before unpegging the Window.Clearing an event source releases its GIT cookies, which revokes the native registrations and allows the managed Window, generated binding objects, and application data to be collected.
Handlers are cleared only after:
Closedevent has been raised.WindowEventArgs.Handled.VisibilityChanged(false)notification has been raised.A canceled close therefore preserves all event subscriptions and existing behavior.
CFTMEventSource::Clearsynchronizes with event raising and handler addition/removal before releasing its registrations.A regression test creates a secondary Window that handles its own
Closedevent, closes it, forces garbage collection, and verifies that the Window is no longer aliveCustomer Impact
WinUI desktop applications that repeatedly create and close secondary Windows no longer accumulate the closed Windows and their managed object graphs.
This includes applications that:
{x:Bind}on a Window, which generates anActivatedhandler.In the reported reproduction, each retained Window held a view model containing a 40 MB array, causing memory usage to grow by approximately 39 MB per closed Window.
Regression Potential
CFTMEventSourceis shared infrastructure, but the newClearoperation is invoked here only for desktop Window event sources. The timing is intentional: handlers remain available whileClosedand the finalVisibilityChangedevent are raised and are cleared only after the close becomes permanent.How Has This Been Tested?
Added
VerifyClosedWindowWithSelfHandlerDoesNotLeaktoMUXControlsTestAppto verify that a secondary Window handling its ownClosedevent is collectible after close.Built
Microsoft.UI.Xaml.dllsuccessfully with no warnings or errors.The original application was also tested against the locally built WinUI binaries using the unpackaged, self-contained deployment approach documented in
GettingStarted.md.Managed heap comparison
After creating and closing ten secondary Windows and forcing garbage collection:
The same test was repeated with
{x:Bind}enabled. NoSubWindow,SubViewModel, generated bindings object, or large array remained after collection.Additional create/close cycles remained bounded instead of growing linearly.
Screenshots (if appropriate)
Not applicable; this change has no visual impact.