Skip to content

fix(🍎): fix memory leaks from unregistered view updates and mapper closures - #3932

Merged
wcandillon merged 2 commits into
Shopify:mainfrom
wcandillon:claude/ios-makeimageview-leak-xhfeab
Jul 10, 2026
Merged

fix(🍎): fix memory leaks from unregistered view updates and mapper closures#3932
wcandillon merged 2 commits into
Shopify:mainfrom
wcandillon:claude/ios-makeimageview-leak-xhfeab

Conversation

@wcandillon

Copy link
Copy Markdown
Contributor

No description provided.

wcandillon and others added 2 commits July 9, 2026 21:23
…stry

On iOS (and Android), every image drawn in a Canvas — most visibly
makeImageFromView snapshots at ~W*H*4 bytes each — could stay resident
after dispose(), GC, and unmount:

1. NativeReanimatedContainer never stopped its Reanimated mapper on
   unmount; stopMapper only ran at the start of the next redraw, which
   never comes for an unmounted Canvas. The leaked mapper closure
   permanently retained the recorder (whose commands hold sk_sp<SkImage>
   copies of every drawn image) and the SkPicture, so the CFData pixel
   copy made in ViewScreenshotService was never released. Stop the
   mapper in unmount() (native and web containers).

2. The leaked mapper (or the queued first-frame runOnUI) kept calling
   setJsiProperty(nativeId, "picture", ...) after the native view had
   unregistered, and ViewRegistry::withViewInfo recreated the erased
   entry, storing the sk_sp<SkPicture> in the process-global registry
   under a nativeId that is never reused — a permanent leak. Tombstone
   unregistered ids so late property updates get a transient info object
   instead of resurrecting the entry (registration paths revive the id,
   which also keeps ids valid across JS reloads).

3. requestRedraw/makeImageSnapshot(Async)/size created empty registry
   entries for unknown ids; they now use a read-only lookup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PsKgiwBDKyJyBcRCGCeQj
@wcandillon
wcandillon merged commit 89f6954 into Shopify:main Jul 10, 2026
41 of 42 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.7.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant