Skip to content

fix: Memory leak when unmounting views mid-animation#9711

Merged
MatiPl01 merged 1 commit into
mainfrom
@matipl01/fix-mid-animation-registry-leak
Jun 22, 2026
Merged

fix: Memory leak when unmounting views mid-animation#9711
MatiPl01 merged 1 commit into
mainfrom
@matipl01/fix-mid-animation-registry-leak

Conversation

@MatiPl01

@MatiPl01 MatiPl01 commented Jun 20, 2026

Copy link
Copy Markdown
Member

Fixes an Android memory leak: tearing down a view subtree while CSS animations are running left the unmounted nodes (and their still-scheduled animations) in every update registry. ReanimatedMountHook returned early on Reanimated's own commits and skipped handleNodeRemovals, so while an animation runs (every frame is a Reanimated commit) the cleanup never ran. It now always drains removable nodes on mount and only gates the commit-unpause on React commits.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an Android memory leak in Fabric mounting where tearing down a view subtree mid-animation could leave removed nodes (and their scheduled CSS animations) registered indefinitely. The mount hook no longer returns early on Reanimated-originated mounts, ensuring removal draining always runs while still only unpausing commits on React-originated mounts.

Changes:

  • Compute whether the mount was initiated by Reanimated via ReanimatedMountTrait, and always unset the trait for cleanliness.
  • Always call UpdatesRegistryManager::handleNodeRemovals (even on Reanimated mounts) to prevent leaks during per-frame animation mounts.
  • Gate unpauseReanimatedCommits() / requestFlush_() so they only run after React commits.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ReanimatedMountHook skipped handleNodeRemovals on Reanimated's own
commits. While CSS animations run, every mount carries the mount trait,
so the cleanup never ran for the duration of the animation. Tearing the
view tree down mid-animation then leaked the unmounted nodes (and their
still-scheduled CSS animations) in all update registries on Android.

Always run handleNodeRemovals; gate only the commit-unpause on React
commits.
@MatiPl01 MatiPl01 force-pushed the @matipl01/fix-mid-animation-registry-leak branch from 157cdd7 to 14b2e6b Compare June 22, 2026 14:47
@MatiPl01 MatiPl01 added this pull request to the merge queue Jun 22, 2026
Merged via the queue into main with commit 8306dc9 Jun 22, 2026
12 checks passed
@MatiPl01 MatiPl01 deleted the @matipl01/fix-mid-animation-registry-leak branch June 22, 2026 15:18
MatiPl01 added a commit that referenced this pull request Jun 25, 2026
…ion (#9711) (#9761)

## Summary

Cherry-picking for Reanimated 4.4.2 release
- #9711
MatiPl01 added a commit that referenced this pull request Jul 2, 2026
…ion (#9711) (#9830)

## Summary

Cherry-picking for Reanimated 4.3.2 release
- #9711

## Cherry-pick notes

Conflict resolution: on 4.3-stable the early return lived directly in
the mount-trait block (and 4.3 has no `setLastMountedRoot`, which came
with #9715), so the change was applied on 4.3's shape -
`handleNodeRemovals` now always runs and only the unpause is gated on
the commit not being a Reanimated mount. Same semantics as on main.
@MatiPl01 MatiPl01 mentioned this pull request Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants