Skip to content
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

Image and ImageBackground memory leaks in iOS? #22448

Closed
3 tasks done
xzilja opened this issue Nov 28, 2018 · 21 comments
Closed
3 tasks done

Image and ImageBackground memory leaks in iOS? #22448

xzilja opened this issue Nov 28, 2018 · 21 comments
Labels
Bug Component: Image Component: ImageBackground Platform: iOS iOS applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@xzilja
Copy link
Contributor

xzilja commented Nov 28, 2018

Environment

  React Native Environment Info:
    System:
      OS: macOS 10.14.1
      CPU: x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
      Memory: 658.77 MB / 16.00 GB
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.11.0 - /usr/local/bin/node
      Yarn: 1.10.1 - /usr/local/bin/yarn
      npm: 6.4.1 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
    IDEs:
      Xcode: 10.1/10B61 - /usr/bin/xcodebuild
    npmPackages:
      @types/react: 16.7.7 => 16.7.7 
      @types/react-native: 0.57.13 => 0.57.13 
      react: 16.7.0-alpha.2 => 16.7.0-alpha.2 
      react-native: 0.57.5 => 0.57.7 
    npmGlobalPackages:
      react-native-cli: 2.0.1

Description

I noticed high memory usage in my app that didn't go away. After tracing for leaks it looks like this is due to images. It seems like iOS is storing all images in memory and is never offloading them. I looked through documentation of Image but didn't find anything related to image caching nor how to offload them manually. Below is my profiler output for leaks

screenshot 2018-11-28 at 13 37 32

Each "spike" happens when new image is used / loaded. All these images are local and stored in Images.xcassets folder i.e. when I load them it looks something like

This happens with images loaded from Images.xcassets as well as ones required locally, i.e.

<Image source={{ uri: 'image_name' }} />

<Image source={require("../src/assets/myImage.png")} />

Note: This is not actually a lot of images loaded on one page, rather me navigating through my app and loading new assets on different views, so images are mounted and unmounted, but memory seems to be accumulating.

@xzilja xzilja changed the title Image and ImageBackground leaks in iOS Image and ImageBackground memory leaks in iOS? Nov 28, 2018
@xzilja
Copy link
Contributor Author

xzilja commented Nov 28, 2018

Possibly related (some of these were closed due to inactivity, but as far as I can tell no solution was present prior to closing)

#2529
#21902
#12220

@xzilja
Copy link
Contributor Author

xzilja commented Dec 3, 2018

UPDATE I got my hands on a low memory device (iPhone 5s running iOS) and wanted to see if iOS auto manages and offloads images from memory, but it was not the case. App keeps all these images in memory and crashes

@xzilja
Copy link
Contributor Author

xzilja commented Dec 3, 2018

If I require images from custom assets folder defined in my project i.e. use require("./assets/someimg.png") graph looks fine, it loads images, but its not accumulating memory and is auto offloading.

screenshot 2018-12-03 at 17 59 50

UPDATE: I think it only happens in development, I guess due to images being loaded over http from packager, or images are minified in release so I can't get my app to crash.

@raphaelrk
Copy link

raphaelrk commented Dec 12, 2018

Also running into this issue but with remote images I save in my filesystem. Showing just ~40 of the same saved image (not that many for the feed app I'm working on) brings my RAM usage over 1gb, at which point my phone reboots.

This doesn't happen when I refer to remote URI's rather than local ones, but then the images flicker / aren't very performative which is why I save them to my device. Haven't checked whether this is also happening on Android since our app hasn't been crashing there.

@raphaelrk
Copy link

raphaelrk commented Dec 12, 2018

Update: made a reproducible demo with this snack. If you open it and show the perf monitor, you'll see as you scroll down the memory usage skyrockets until the point at which your phone crashes. Whereas if you switch out the local URIs for the remote URIs, memory usage stays low (but then you get flickering when mounting / unmounting these images).

@stale
Copy link

stale bot commented Aug 4, 2019

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 4, 2019
@xzilja
Copy link
Contributor Author

xzilja commented Aug 6, 2019

Still an issue

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 6, 2019
@stale
Copy link

stale bot commented Nov 4, 2019

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 4, 2019
@raphaelrk
Copy link

Still an issue: updated snack for expo 35

Testing on physical iPhone Xs on iOS 13.1.3, using the cached images crashes and reboots my phone, while using the remote images works smoothly.

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Nov 7, 2019
@stale
Copy link

stale bot commented Feb 5, 2020

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 5, 2020
@raphaelrk
Copy link

Still seeing the same testing on expo 36

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 5, 2020
@xzilja
Copy link
Contributor Author

xzilja commented Feb 6, 2020

issue also persists in rn 61

@mohamedshuaau
Copy link

I am seeing 100+ new leaks and I am really not sure where this is occurring. I am not that experienced on IOS but I have my app running on iPhone. It starts off with 1000 memory leaks and there are new 100+ leaks everytime

@peterzanetti
Copy link

How are people working around this? Surely there are apps that have more than a handful of images in them?

@raphaelrk
Copy link

@peterzanetti I moved to using resized/compressed images after first running into this and that helped a ton. Previously my app was loading lots of high quality profile pictures over and over, now it loads 100, 320, or 800px wide compressed jpegs depending on how big the image will appear in the app.

@peterzanetti
Copy link

It seems insane to me that working with lots of high quality images is somehow unusual for a modern iOS app. When an image is not mounted, it should not be in memory. Period.

@MegaMaddin
Copy link

Sounds stupid, but worked in our case - for the assets stored within the app package, we switched to using PNGs. It's a bit more storage intensive and increases the app size, but that solved [as in workaround] the memory issues for us.

@jordangrant
Copy link

Big issue for me. Local bundled image assets all stored in memory and never released. Accumulates and crashes. ImageBackground component.

@jordangrant
Copy link

jordangrant commented Oct 4, 2020

Solution for my app, Staats which has over 225 images bundled as templates.

  1. Resize all local, bundled assets (Xcassets and android drawable folder) to 414x896 @ 458ppi (max iPhone res)
  2. Save as PNG-8 (vs PNG-24)
  3. Compress resulting images on tinyPNG.com

The reason I did this is because of DylanVann/react-native-fast-image#715 (comment) which states the resolution matters, not just the filesize!
This immediately dropped my memory usage from 1.2GB -> 885MB

When loading all my images at once (View All) my app easily crept up to 1.7GB and crashed.
After resizing the main images, it holds at 1.17GB.

If I use the app for an extended period of time, and load every (hundreds) of templates I'm still able to crash the app, so still lots of room for improvement...

Edit: After further resizing even more of my assets, memory stays below 900MB.

facebook-github-bot pushed a commit that referenced this issue Oct 12, 2021
Summary:
This sync includes the following changes:
- **[579c008a7](facebook/react@579c008a7 )**: [Fizz/Flight] pipeToNodeWritable(..., writable).startWriting() -> renderToPipeableStream(...).pipe(writable) ([#22450](facebook/react#22450)) //<Sebastian Markbåge>//
- **[f2c381131](facebook/react@f2c381131 )**: fix: useSyncExternalStoreExtra ([#22500](facebook/react#22500)) //<Daishi Kato>//
- **[0ecbbe142](facebook/react@0ecbbe142 )**: Sync hydrate discrete events in capture phase and dont replay discrete events ([#22448](facebook/react#22448)) //<salazarm>//
- **[a724a3b57](facebook/react@a724a3b57 )**: [RFC] Codemod invariant -> throw new Error ([#22435](facebook/react#22435)) //<Andrew Clark>//
- **[201af81b0](facebook/react@201af81b0 )**: Release pooled cache reference in complete/unwind ([#22464](facebook/react#22464)) //<Joseph Savona>//
- **[033efe731](facebook/react@033efe731 )**: Call get snapshot in useSyncExternalStore server shim ([#22453](facebook/react#22453)) //<salazarm>//
- **[7843b142a](facebook/react@7843b142a )**: [Fizz/Flight] Pass in Destination lazily to startFlowing instead of in createRequest ([#22449](facebook/react#22449)) //<Sebastian Markbåge>//
- **[d9fb383d6](facebook/react@d9fb383d6 )**: Extract queueing logic into shared functions ([#22452](facebook/react#22452)) //<Andrew Clark>//
- **[9175f4d15](facebook/react@9175f4d15 )**: Scheduling Profiler: Show Suspense resource .displayName ([#22451](facebook/react#22451)) //<Brian Vaughn>//
- **[eba248c39](facebook/react@eba248c39 )**: [Fizz/Flight] Remove reentrancy hack ([#22446](facebook/react#22446)) //<Sebastian Markbåge>//
- **[66388150e](facebook/react@66388150e )**: Remove usereducer eager bailout ([#22445](facebook/react#22445)) //<Joseph Savona>//
- **[d3e086932](facebook/react@d3e086932 )**: Make root.unmount() synchronous  ([#22444](facebook/react#22444)) //<Andrew Clark>//
- **[2cc6d79c9](facebook/react@2cc6d79c9 )**: Rename onReadyToStream to onCompleteShell ([#22443](facebook/react#22443)) //<Sebastian Markbåge>//
- **[c88fb49d3](facebook/react@c88fb49d3 )**: Improve DEV errors if string coercion throws (Temporal.*, Symbol, etc.) ([#22064](facebook/react#22064)) //<Justin Grant>//
- **[05726d72c](facebook/react@05726d72c )**: [Fix] Errors should not "unsuspend" a transition ([#22423](facebook/react#22423)) //<Andrew Clark>//
- **[3746eaf98](facebook/react@3746eaf98 )**: Packages/React/src/ReactLazy ---> changing -1 to unintialized ([#22421](facebook/react#22421)) //<BIKI DAS>//
- **[04ccc01d9](facebook/react@04ccc01d9 )**: Hydration errors should force a client render ([#22416](facebook/react#22416)) //<Andrew Clark>//
- **[029fdcebb](facebook/react@029fdcebb )**: root.hydrate -> root.isDehydrated ([#22420](facebook/react#22420)) //<Andrew Clark>//
- **[af87f5a83](facebook/react@af87f5a83 )**: Scheduling Profiler marks should include thrown Errors ([#22417](facebook/react#22417)) //<Brian Vaughn>//
- **[d47339ea3](facebook/react@d47339ea3 )**: [Fizz] Remove assignID mechanism ([#22410](facebook/react#22410)) //<Sebastian Markbåge>//
- **[3a50d9557](facebook/react@3a50d9557 )**: Never attach ping listeners in legacy Suspense ([#22407](facebook/react#22407)) //<Andrew Clark>//
- **[82c8fa90b](facebook/react@82c8fa90b )**: Add back useMutableSource temporarily ([#22396](facebook/react#22396)) //<Andrew Clark>//
- **[5b57bc6e3](facebook/react@5b57bc6e3 )**: [Draft] don't patch console during first render ([#22308](facebook/react#22308)) //<Luna Ruan>//
- **[cf07c3df1](facebook/react@cf07c3df1 )**: Delete all but one `build2` reference ([#22391](facebook/react#22391)) //<Andrew Clark>//
- **[bb0d06935](facebook/react@bb0d06935 )**: [build2 -> build] Local scripts //<Andrew Clark>//
- **[0c81d347b](facebook/react@0c81d347b )**: Write artifacts to `build` instead of `build2` //<Andrew Clark>//
- **[4da03c9fb](facebook/react@4da03c9fb )**: useSyncExternalStore React Native version ([#22367](facebook/react#22367)) //<salazarm>//
- **[48d475c9e](facebook/react@48d475c9e )**: correct typos ([#22294](facebook/react#22294)) //<Bowen>//
- **[cb6c619c0](facebook/react@cb6c619c0 )**: Remove Fiber fields that were used for hydrating useMutableSource ([#22368](facebook/react#22368)) //<Sebastian Silbermann>//
- **[64e70f82e](facebook/react@64e70f82e )**: [Fizz] add avoidThisFallback support ([#22318](facebook/react#22318)) //<salazarm>//
- **[3ee7a004e](facebook/react@3ee7a004e )**: devtools: Display actual ReactDOM API name in root type ([#22363](facebook/react#22363)) //<Sebastian Silbermann>//
- **[79b8fc667](facebook/react@79b8fc667 )**: Implement getServerSnapshot in userspace shim ([#22359](facebook/react#22359)) //<Andrew Clark>//
- **[86b3e2461](facebook/react@86b3e2461 )**: Implement useSyncExternalStore on server ([#22347](facebook/react#22347)) //<Andrew Clark>//
- **[8209de269](facebook/react@8209de269 )**: Delete useMutableSource implementation ([#22292](facebook/react#22292)) //<Andrew Clark>//

Changelog:
[General][Changed] - React Native sync for revisions e8feb11...afcb9cd

jest_e2e[run_all_tests]

Reviewed By: yungsters

Differential Revision: D31541359

fbshipit-source-id: c35941bc303fdf55cb061e9996200dc868a6f2af
@github-actions
Copy link

github-actions bot commented Mar 4, 2023

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Mar 4, 2023
@github-actions
Copy link

This issue was closed because it has been stalled for 7 days with no activity.

@facebook facebook locked as resolved and limited conversation to collaborators Mar 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Component: Image Component: ImageBackground Platform: iOS iOS applications. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

8 participants