react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Memory Leak with latest React Native Integrated App on v0.74.2

Open satheshrgs-rksv opened this issue 1 year ago • 22 comments

Description

Facing Memory Leak with React Native app integrated with existing native app.

I am currently on React Native 0.71.1 and tried to update to React Native 0.74.2.After upgrade facing memory leak. Memory usage keeps on increasing. With version 0.72 also there is no leak faced. But from version 0.73 facing memory leak.

Following this react native callstack brownfield architecture to load react native inside existing app as we have multiple entry points from native app to load react native in Fragment and also in Activity.

Steps to reproduce

  1. Clone the repo - https://github.com/callstack/react-native-brownfield
  2. Do yarn install
  3. Try to open the example kotlin app
  4. Open profiler from android studio
  5. Perform Action like Click on Open React Native Button
  6. Capture the Heapdump

React Native Version

0.74.2

Affected Platforms

Runtime - Android

Output of npx react-native info

System:
  OS: macOS 14.5
  CPU: (10) arm64 Apple M1 Pro
  Memory: 125.97 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.20.1
    path: ~/.nvm/versions/node/v18.20.1/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.nvm/versions/node/v18.20.1/bin/yarn
  npm:
    version: 10.5.0
    path: ~/.nvm/versions/node/v18.20.1/bin/npm
  Watchman:
    version: 2024.05.06.00
    path: /opt/homebrew/bin/watchman
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: Not Found
IDEs:
  Android Studio: 2024.1 AI-241.15989.150.2411.11948838
  Xcode:
    version: 15.4/15F31d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /Users/satheshrangasamy/.jenv/shims/javac
  Ruby:
    version: 2.7.4
    path: /Users/satheshrangasamy/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.2
    wanted: 0.74.2
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

Stacktrace or Logs

Attached Memory Leak Profiler ScreenShot

Reproducer

https://github.com/satheshrgs-rksv/memoryleakreproducer

Screenshots and Videos

Screenshot 2024-06-28 at 17 18 32

image

satheshrgs-rksv avatar Jun 28 '24 11:06 satheshrgs-rksv

@cortinico can you please look into this issue.

satheshrgs-rksv avatar Jun 30 '24 22:06 satheshrgs-rksv

Facing the same issue

AbhiGojoko avatar Jul 01 '24 06:07 AbhiGojoko

We are facing the same issue since 0.73.0. do we have any solution to this?

harsh-rksv avatar Jul 01 '24 07:07 harsh-rksv

I am currently on React Native 0.71.1 and tried to update to React Native 0.74.2.After upgrade facing memory leak. Memory usage keeps on increasing. With version 0.72 also there is no leak faced. But from version 0.73 facing memory leak.

Can you try to update incrementally (first to 0.72 and then 0.73) and mention where you notice this regression?

cortinico avatar Jul 01 '24 11:07 cortinico

Facing this issue from 0.73 version. 72.x works fine

satheshrgs-rksv avatar Jul 01 '24 13:07 satheshrgs-rksv

Facing the same memory leak issue.

@cortinico This issue has been mentioned many times previously also. Kindly check this issue on priority. It is affecting all our integrated apps currently.

Previously raised issues:

https://github.com/facebook/react-native/issues/37105

Gogul-S avatar Jul 02 '24 13:07 Gogul-S

@cortinico

Here are some more finding from my side for the memory leak

I used this repo rn-diff-purge repo for taking android folders and followed the steps mentioned here in https://reactnative.dev/docs/integration-with-existing-apps for integration

Here's what I did in this repo - https://github.com/satheshrgs-rksv/memoryleakreproducer. Please use this as reproducer

  1. created a folder and added index.js and package.json as mentioned in the official docs
  2. copied the android folder from rn-diff-purge-repo
  3. moved the existing MainApplication and MainActivity files to package bootstrapinbuilt
  4. created a new package with the contents from react-native-brownfield
  5. create a dummy landing page in native with two buttons, one will open the RN activity as mentioned in official docs and another will open based on brownfield approach

Following are some of the methods i tried

Method 1: Directly launcing the RN app using the existing MainApplication and MainActivity from inbuilt rn-diff-app

Method 2: Directly launching the RN app with the ReactNativeActivity created with reference from official docs

Method 3: Create a screen in native, with a button and on click of that it will open the React Native activity created with reference from Official docs

Method 4: Create a screen in native, with a button and on click of that it will open the React Native activity created with reference from Brownfield

Findings: I have tried with RN version 0.71.1 and 0.74.3. When I run profiler based with the above methods following are the findings

  • Method 1: No leak in both RN versions
  • Method 2: No leak in both RN versions
  • Method 3: Multiple Leaks Seen when opening and closing the activity in both RN versions
  • Method 4: With RN version 0.71.1, only one leak is seen, but with RN version 0.74.3 multiple leaks are seen

satheshrgs-rksv avatar Jul 04 '24 12:07 satheshrgs-rksv

Profiler Screenshots from version 0.71.1

Method 1 0 71 1 Method 1

Method 2 0 71 1 Method 2

Method 3 0 71 1 Method 3

Method 4 0 71 1 Method 4

satheshrgs-rksv avatar Jul 04 '24 12:07 satheshrgs-rksv

Profiler Screenshots from version 0.74.3

Method 1 0 74 3 Method 1

Method 2 0 74 3 Method 2

Method 3 0 74 3 Method 3

Method 4 0 74 3 Method 4

satheshrgs-rksv avatar Jul 04 '24 12:07 satheshrgs-rksv

The main thing which we need to figure out is why in the latest versions of react native with brownfield approach multiple leaks are seen

satheshrgs-rksv avatar Jul 04 '24 12:07 satheshrgs-rksv

Please see this comment from @fannnzhang

@cortinico Since we are nearing the android deadline for android 14 support and since ours is an integrated app running on 0.71.1, upgrading to latest versions of React Native is a must for this update. Could you please help with this as soon as possible

satheshrgs-rksv avatar Jul 08 '24 07:07 satheshrgs-rksv

@cortinico Any update on this ?

satheshrgs-rksv avatar Jul 29 '24 13:07 satheshrgs-rksv

I meet the same issue when integrate react native to my Android App, Any update on this? BestRegards,

baka3k avatar Aug 08 '24 07:08 baka3k

I cant even run the build in android and badly need to support my app in Android 14 and upcoming Android 15.

Gautham495 avatar Aug 17 '24 14:08 Gautham495

I faced issue Android memory leak in pure react-native (not integration app) when running foreground still not resolve serviceshttps://github.com/facebook/react-native/issues/45001

chanphiromsok avatar Aug 19 '24 01:08 chanphiromsok

Same here

samrombswm avatar Aug 19 '24 22:08 samrombswm

We have a hybrid app where we in our ApplicationController we are:

private fun initReactNative() {
        SoLoader.init(this, false)
        ApplicationLifecycleDispatcher.onApplicationCreate(this)
        reactNativeHost.reactInstanceManager.createReactContextInBackground()
    }

but then use a ReactActivity:

class RNFeedbackActivity : ReactActivity() {
    override fun getMainComponentName(): String {
        return "AppFeedback"
    }

    companion object {
        fun startActivity(context: Context) {
            val intent = Intent(context, RNFeedbackActivity::class.java)
                .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)

            context.startActivity(intent)
        }
    }
}

we use that startActivity method to actually start everything.

We see this memory leak come up when we go in/out of that activity

boxman0617 avatar Aug 19 '24 22:08 boxman0617

@satheshrgs-rksv May I ask if you are using new arch? We are experiencing the same issue and we use new arch.

yzhe554 avatar Aug 23 '24 01:08 yzhe554

@yzhe554 No, not using new arch

satheshrgs-rksv avatar Aug 23 '24 01:08 satheshrgs-rksv

@cortinico Any update on this? I believe the issue blocks many brownfield projects.

yzhe554 avatar Aug 23 '24 01:08 yzhe554

@cortinico Any update on this? I believe the issue blocks many brownfield projects.

Nope there are no updates here. Once we have updates, we'll post them.

With version 0.72 also there is no leak faced. But from version 0.73 facing memory leak.

At this stage, the best you folks can do is keep on investigating where the leak is. Mentioning that "multiple leaks" are happening is not really helpful for us to debug. Any investigation now is more than welcome.

Also better reproducers would help (like simpler apps rather than https://github.com/callstack/react-native-brownfield)

cortinico avatar Aug 27 '24 10:08 cortinico

@cortinico

Method 3: Create a screen in native, with a button and on click of that it will open the React Native activity created with reference from Official docs

https://github.com/satheshrgs-rksv/memoryleakreproducer

satheshrgs-rksv avatar Aug 27 '24 11:08 satheshrgs-rksv

Hi - I'm also working on a brownfield app and this memory leak has also impacted my app since upgrading to React Native 0.73.1. In my case, the problem is so severe that my app got flagged by Google Play for reaching the App Not Responding bad behavior threshold, which may impact the app's search results in the store.

I'd like to share my research results that hopefully can help those who are experiencing the problem.

TL;DR

Reverting this commit from the React Native source seems to resolve the memory leak issue but might have an impact on apps using ReactInstanceManager#recreateReactContextInBackground. Applying this fix may require Build from source.
MY FINDINGS

I created a minimal brownfield project in order to investigate the issue. The app has only two screens/activities:

  • An Android native screen (the main activity) with a button to navigate to a React screen. When the button is clicked, it callsActivity#startActivity to start a new activity with the embedded RN view.
  • The RN screen (another Activity) with only a simple Image component. Screenshot 2024-09-19 at 10 01 02


I tried two RN versions 0.72.17 and 0.75.3 and noticed some important things when entering and leaving the RN screen:

  • With RN 0.72.17, both functions createViewInstance (when entering the screen) and onDropViewInstance (when leaving the screen) are triggered for the Image component which is expected.
  • With RN 0.75.3, only createViewInstance is triggered when entering the screen. onDropViewInstance is not triggered when leaving the screen. This is clearly the sign of a memory leak. Screenshot 2024-09-19 at 10 24 29 Screenshot 2024-09-19 at 10 27 17


Then I investigated the code changes between 0.72.17 and 0.73.0 and I found this commit that seems very likely be the cause of the leak. While the purpose of the commit is to clean up the views in the screen's root view, it somehow prevents the cleanup process of native components inside the screen from happening. So I tried reverting the changes in the commit and could see that the cleanup process happened as expected, onDropViewInstance was called, and the memory leak disappeared.

Since I don't understand the codebase well enough, it's hard for me to come up with a reasonable fix for the memory leak. While reverting the mentioned commit could resolve the issue, it would defeat the purpose of the commit.

I hope my research results help the React Native team more easily figure out and fix this problem. Feel free to tell me if there is anything more I can help with and I'm happy to have further discussion on this topic.

tranhoangduong1994 avatar Sep 19 '24 04:09 tranhoangduong1994

@tranhoangduong1994 Thank you! I can also verify the issue is gone after patching a revert.

Update: I just profile this again with new arch, I can still see memory leaks but just less.

yzhe554 avatar Sep 20 '24 04:09 yzhe554

my issue still remain when running foreground service -> clear the app -> open app again MainActivity still leak

chanphiromsok avatar Sep 20 '24 06:09 chanphiromsok

@cortinico Is https://github.com/facebook/react-native/pull/41678 related to this ?

satheshrgs-rksv avatar Nov 27 '24 12:11 satheshrgs-rksv

Hi @satheshrgs-rksv , have you got this resolved?

yzhe554 avatar Apr 16 '25 15:04 yzhe554

Haven't tried updating yet

satheshrgs-rksv avatar Apr 17 '25 04:04 satheshrgs-rksv

Although I am not using brownfield but react-native-navigation, I am getting more and more ANR reports after upgrading to 0.75, I suspect the root cause is similar.

tarouboy avatar May 12 '25 14:05 tarouboy