Description
Describe the bug
In the process of debugging a memory leak and subsequent crash in our React Native app (iOS), I decided to try out the demo implementation and see if there would be a problem in this minimal setting. This issue is related to the problem mentioned in #146 it seems.
When trying to select and upload JPEG/PNG files using the demo app the following behaviour can be observed both using the XCode debugger or React Native Debugger/Perf Monitor in Expo:
- After an image is selected using the image picker, memory consumption goes up by a significant amount (more than the compressed file size of a JPEG, about 50% of the size of an uncompressed JPEG)
- starting the upload peaks the memory consumption even further (way above the file size of the file being transferred)
- during upload memory consumption remains stable
- after a successful upload, memory is reclaimed but not all the way back to the original level
- this leads to the app running out of memory over time and crashing.
It is notable that, that the memory consumption after picking an image and during the upload is much higher than the file being transferred.
I tried creating a log in instruments (where the behaviour can be followed as well) however using instruments seems to lead to problems with the transfers resulting in timeouts for large files.
Any pointers/help would be very appreciated! Thanks in advance!
To Reproduce
Run the app using expo or eject the app and run it using XCode. Select and upload the files and watch the memory usage in XCode or Perf Monitor.
While this issue can be observed with files of any size, it is most prominent with large files.
I have compiled a selection of large JPEGs in order to make the issue easily visible.
Expected behavior
- Memory footprint after uploading should match the original memory consumption (prior to using the image picker)
Current behavior
To better illustrate the situation, here is a log of memory footprint snapshot after triggering different events
-
app start: 60.5 MB
-
selected a 9.5 MB JPEG (43 MB uncompressed): 85.9 MB
-
started upload: 114 MB
-
upload completed: 99.8 MB
-
restarted upload: 128 MB
-
received "Reloading image" message: 143 MB
"2019-12-10 14:22:27.764 [info][tid:main][RCTImageView.m:422] Reloading image file:///var/mobile/Containers/Data/Application/9FA540E3-0CD4-41D6-B5D7-E7C769960F69/Library/Caches/ImagePicker/EBDD4F4B-410C-48EB-ACF4-E70143724102.jpg as size {2964.5, 200}" -
upload completed: 114 MB
-
restarted upload: 142 MB
-
upload complete: 130 MB
-
restarted upload: 157 MB
-
upload complete: 142 MB
-
(… rinse and repeat …): 199 MB
-
picked a 36MB JPEG (285 MB uncompressed): 377 MB
-
started upload: 456 MB
-
upload complete: 393 MB
-
restarted upload: 667 MB
-
upload complete 465 MB
-
restarted upload: 601 MB
-
upload complete: 536 MB
You get the idea… After enough tries the app crashes due to lack of memory.
Setup details
- Runtime environment: React Native (iOS)
- Used tus-js-client version: 1.8.0
- Used tus server software: N/A (using the https://master.tus.io/files/ endpoint)