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

OutOfMemoryError in BlobModule when using fetch + large file [Android] #48657

Open
giantslogik opened this issue Jan 14, 2025 · 1 comment · May be fixed by #48766
Open

OutOfMemoryError in BlobModule when using fetch + large file [Android] #48657

giantslogik opened this issue Jan 14, 2025 · 1 comment · May be fixed by #48766
Labels
Needs: Triage 🔍 🌐Networking Related to a networking API. Platform: Android Android applications.

Comments

@giantslogik
Copy link

giantslogik commented Jan 14, 2025

Description

create a blob from a file url. (A ~400 MB UHD video).

      const response = await fetch(uri);
      const blob = await response.blob(); 

It fails on Android with an underlying OutOfMemory error. Works on iOS.

The underlying ReactAndroid code is inefficient in its buffer management. It should determine the file size and allocate a fixed size buffer rather than using the buffer resize logic in java.io.ByteArrayOutputStream.ensureCapacity. It should also close the InputStream after reading it into the buffer.

Steps to reproduce

  1. Install the application with yarn android
  2. Attach android logcat to capture the underlying error
  3. You need a large video file to reproduce the error. (I used a 440 MB .mp4 file. The reproducer uses a large heap , without large heap the error happens for even smaller files . )
  4. Click the 'Choose a large file' button and select a large video file.

React Native Version

0.76.6

Affected Platforms

Runtime - Android

Output of npx react-native info

System:
  OS: macOS 14.4
  CPU: (16) arm64 Apple M3 Max
  Memory: 231.39 MB / 48.00 GB
  Shell:
    version: 3.2.57
    path: /bin/bash
Binaries:
  Node:
    version: 20.17.0
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.19
    path: /usr/local/bin/yarn
  npm:
    version: 10.8.3
    path: /usr/local/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.15.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.5
      - iOS 17.5
      - macOS 14.5
      - tvOS 17.5
      - visionOS 1.2
      - watchOS 10.5
  Android SDK:
    API Levels:
      - "23"
      - "27"
      - "28"
      - "29"
      - "30"
      - "31"
      - "32"
      - "33"
      - "33"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 19.1.0
      - 20.0.0
      - 21.1.2
      - 22.0.1
      - 23.0.1
      - 23.0.2
      - 23.0.3
      - 24.0.0
      - 24.0.1
      - 24.0.2
      - 24.0.3
      - 25.0.0
      - 25.0.1
      - 25.0.2
      - 25.0.3
      - 26.0.0
      - 26.0.1
      - 26.0.2
      - 26.0.3
      - 27.0.0
      - 27.0.1
      - 27.0.2
      - 27.0.3
      - 28.0.0
      - 28.0.1
      - 28.0.2
      - 28.0.3
      - 29.0.0
      - 29.0.1
      - 29.0.2
      - 29.0.3
      - 30.0.0
      - 30.0.1
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 32.0.0
      - 32.1.0
      - 33.0.0
      - 33.0.1
      - 33.0.2
      - 34.0.0
      - 34.0.0
      - 34.0.0
      - 34.0.0
      - 35.0.0
    System Images:
      - android-30 | Google Play ARM 64 v8a
      - android-32 | Google Play ARM 64 v8a
      - android-33 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.10811636
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.8.1
    path: /usr/bin/javac
  Ruby:
    version: 3.3.0
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.6
    wanted: 0.76.6
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

Failed to send url request: content://media/external/video/media/1000024367
java.lang.OutOfMemoryError: Failed to allocate a 536870928 byte allocation with 100663296 free bytes and 251MB until OOM, target footprint 374277184, growth limit 536870912
at java.util.Arrays.copyOf(Arrays.java:3585)
at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:120)
at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:95)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:156)
at com.facebook.react.modules.blob.BlobModule.getBytesFromUri(BlobModule.java:239)
at com.facebook.react.modules.blob.BlobModule.-$$Nest$mgetBytesFromUri(Unknown Source:0)
at com.facebook.react.modules.blob.BlobModule$2.fetch(BlobModule.java:83)
at com.facebook.react.modules.network.NetworkingModule.sendRequestInternal(NetworkingModule.java:282)
at com.facebook.react.modules.network.NetworkingModule.sendRequest(NetworkingModule.java:243)
at com.facebook.jni.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:991)
at android.os.Handler.dispatchMessage(Handler.java:102)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl.lambda$startNewBackgroundThread$2(MessageQueueThreadImpl.java:217)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$$ExternalSyntheticLambda1.run(D8$$SyntheticClass:0)
at java.lang.Thread.run(Thread.java:1012)

Reproducer

https://github.com/giantslogik/blob-large-file-fetch

Screenshots and Videos

No response

@react-native-bot react-native-bot added Platform: Android Android applications. 🌐Networking Related to a networking API. labels Jan 14, 2025
@giantslogik
Copy link
Author

giantslogik commented Jan 17, 2025

When fixing this i ran into a further bug in the fetch support on android. fetch does not handle the Android 'content:' scheme.
It specifically fails here as status is 0 and schemeis 'content://' and not 'file://'

#48762

@giantslogik giantslogik linked a pull request Jan 17, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Triage 🔍 🌐Networking Related to a networking API. Platform: Android Android applications.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants