react-native: Fetching specific JSON causes massive memory leak
Environment
React Native Environment Info:
System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 6.28 GB / 32.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.6.0 - ~/.nvm/versions/node/v10.6.0/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 6.1.0 - ~/.nvm/versions/node/v10.6.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
Android SDK:
Build Tools: 23.0.1, 25.0.0, 26.0.1, 26.0.2, 26.0.3, 28.0.1
API Levels: 23, 26, 28
IDEs:
Android Studio: 3.1 AI-173.4819257
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: 16.4.1 => 16.4.1
react-native: ^0.56.0 => 0.56.0
npmGlobalPackages:
react-native-git-upgrade: 0.2.7
Description
Downloading this <1 KiB JSON file once a second, parsing the JSON, and appending the resultant JSON to an array, causes the demo app below to hit 500MiB of memory usage in less than 15 seconds. Each request permanently allocates ~35MiB of memory.
Reproducible Demo
I have created a repo to reproduce the issue.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 20 (12 by maintainers)
Commits related to this issue
- Release underlying resources when JS instance in GC'ed on iOS (#24405) Summary: Our Blob implementation was very problematic because it didn't release its underlying resource when the JS instance was... — committed to facebook/react-native by janicduplessis 5 years ago
- Release underlying resources when JS instance in GC'ed (#24745) Summary: Our Blob implementation was very problematic because it didn't release its underlying resource when the JS instance was dealoc... — committed to facebook/react-native by janicduplessis 5 years ago
Hmm… I took a quick look at the code to the repro in #23801, and on first glance I think they are different. But it’s very possible they are caused by some of the same underlying issues.
Pulling from my comment above:
The first issue doesn’t seem to apply in #23801, as the size of their downloaded file is pretty substantial (5 MiB) in contrast with the tiny file here (<1 KiB).
The second issue doesn’t seem to apply either. In the repro for #23801, the author actually never keeps anything from the network request around, whereas I was only able to demonstrate my “massive” memory leak by keeping the resultant JSON blob and appending it to an array. My issue goes away if I simply clone the JSON blob and keep that instead of keeping what
fetch
returns to me.It appears that there are two distinct memory leak issues: one that none of the native resources for the network request are cleaned up unless the resultant JS resources are garbage-collected, and the other that some of the native resources aren’t cleaned up even if JS resources are never allocated.