Fix undisposed PointerEvent JSObject on browser pointer move - #22112
Fix undisposed PointerEvent JSObject on browser pointer move#22112appel1 wants to merge 2 commits into
Conversation
OnPointerMove dropped argsObj (the JSObject wrapping the native DOM PointerEvent) without disposing it, except inside a Lazy factory only evaluated when GetIntermediatePoints() is called - which doesn't happen for ordinary moves/hover. Without explicit Dispose(), release requires two steps: Mono GC must collect the abandoned JSObject wrapper to release its JS handle, then V8 can reclaim the underlying JS object. Verified with a standalone FinalizationRegistry-based repro that Mono GC does not trigger on its own under continuous pointermove-like allocation pressure, so undisposed objects pile up - not a permanent leak though. Fix by disposing argsObj in a finally block after routing, guaranteeing deterministic release instead of depending on GC timing. Coalesced-event resolution (GetCoalescedEvents) is unaffected since it only runs synchronously within the same call when a consumer needs it.
|
You can test this PR using the following package version. |
| try | ||
| { | ||
| // Note: routing here is only synchronous when _rawEventGrouper is null (the branch above | ||
| // that creates the Lazy referencing argsObj). When _rawEventGrouper is set, ScheduleInput |
There was a problem hiding this comment.
ScheduleInput context is a good comment, clearing that dispose is safe here. But it can be greatly reduced (and better formatted).
Please follow AI guidelines: https://github.com/appel1/Avalonia/blob/328a7cfbec11bdbe471652b5335658dc22899bd2/CONTRIBUTING.md#ai-guidelines
There was a problem hiding this comment.
I just realized, maybe it isn't so safe after all. Nothing stops an event listener from saving the RawTouchEventArgs and accessing the IntermediatePoints Lazy later after argsObj has been disposed.
Is that still ok? Is it implied that you should only touch event args objects during the event handler?
|
You can test this PR using the following package version. |
OnPointerMove dropped argsObj (the JSObject wrapping the native DOM PointerEvent) without disposing it, except inside a Lazy factory only evaluated when GetIntermediatePoints() is called - which doesn't happen for ordinary moves/hover.
What does the pull request do?
Fix by disposing argsObj in a finally block after routing, guaranteeing deterministic release instead of depending on GC timing. Coalesced-event resolution (GetCoalescedEvents) is unaffected since it only runs synchronously within the same call when a consumer needs it.
What is the current behavior?
Without explicit Dispose(), release requires two steps: Mono GC must collect the abandoned JSObject wrapper to release its JS handle, then V8 can reclaim the underlying JS object. Verified with a standalone FinalizationRegistry-based repro that Mono GC does not trigger on its own under continuous pointermove-like allocation pressure, so undisposed objects pile up - not a permanent leak though.
What is the updated/expected behavior with this PR?
Reduced memory pressure.