-
-
Notifications
You must be signed in to change notification settings - Fork 534
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
Memory Leak. iOS. Strong reference cycle between RNSScreen and RNSScreenView #1754
Comments
I believe we are seeing the same issue. Navigating back and forth between 2 screens causes memory to consistently go up. |
@kkafar do you have any progress on this issue? We have found that this memory leak is the main reason why application crashes because of low memory conditions. In our app we open and close react-native instances a lot. |
Can I get confirmation that this: Fixes the issue in your case? You can try it out by installing screens from the last commit of that PR:
"react-native-screens": "software-mansion/react-native-screens#751aab52a043d33e8d13a53de5688e3436a2ef95" |
alike |
This problem still exists in version 3.22.1. |
My app is a native app that has infiltrated the RN module. When closing RN and returning to the native module, RTCxxxView cannot trigger the dealloc function . (The RTCxxxViewManage dealloc function will trigger) |
|
@kkafar, looks like your fix works for our case. I have checked your branch: "react-native-screens": "software-mansion/react-native-screens#@kkafar/retain-cycle-ios" |
Has the official version been released |
Hey,
No, I have not merged it into main branch yet, as the solution I've provided solves this issue, but causes few other ones (e. g. tab navigation crashes). The issue here is that while dismissing react native view controller from native side |
@sunhongda, while you are waiting for a fix you may use our workaround: #1754 (comment) |
thks |
Android also has similar problems, is there any temporary solution to solve it |
Android also has similar problems, is there any temporary solution to solve it |
Android leak |
Summary: Talking about Paper & iOS here. In standard RN applications when a native component is removed permanently from view hierarchy [it is invalidated (if it implements `RCTInvalidating`)](https://github.com/facebook/react-native/blob/e64756ae5bb5c0607a4d97a134620fafcb132b3b/packages/react-native/React/Modules/RCTUIManager.m#L483-L495). Components that implement `RCTInvalidating` such as [`RNSScreenView`](https://github.com/software-mansion/react-native-screens/blob/9fb3bd00850bcdf29b46daa57e56eabda3ae30ea/ios/RNSScreen.mm#L35) of [`react-native-screens`](https://github.com/software-mansion/react-native-screens) library rely on `RCTInvalidating#invalidate` method being called in adequate moment to release retained resources (in my case the `RNSScreenView` holds a strong reference to it's view controller preventing it from being garbage collected). However in case of brownfield applications (React Native is used only for a particular view & loaded on demand, see: software-mansion/react-native-screens#1754 for discussion & app example) when view controller holding `RCTRootView` is dismissed and whole `React Native` managed view / controller tree gets deallocated, `RCTInvalidating#invalidate` method is not called on the dismissed components, thus in my particular use case, leading to memory leak. Right now I've added call to `RCTUIManager#_purgeChildren:fromRegistry:` (which internally invalidates all components which implement `RCTInvalidating`) in `RCTUIManager#invalidate`. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [IOS][FIXED] - Purge children from view registry on `RCTUIManager` invalidation. Pull Request resolved: #38617 Test Plan: You can run the [demo](https://github.com/mkondakov/RNSScreensMemoryLeak) provided in the [issue](software-mansion/react-native-screens#1754). Following screenshots show that memory leak in brownfield application is resolved. Without the change (`invalidate` method is not being called on native components)  With the change:  Reviewed By: NickGerleman Differential Revision: D49952215 Pulled By: javache fbshipit-source-id: 6336b86774615acc40279c97e6ae0bb777bda8ad
Hey, as my PR to React Native is merged I'm closing the issue. I do not know in which RN version it will be first included, but will keep you updated. |
Summary: Talking about Paper & iOS here. In standard RN applications when a native component is removed permanently from view hierarchy [it is invalidated (if it implements `RCTInvalidating`)](https://github.com/facebook/react-native/blob/e64756ae5bb5c0607a4d97a134620fafcb132b3b/packages/react-native/React/Modules/RCTUIManager.m#L483-L495). Components that implement `RCTInvalidating` such as [`RNSScreenView`](https://github.com/software-mansion/react-native-screens/blob/9fb3bd00850bcdf29b46daa57e56eabda3ae30ea/ios/RNSScreen.mm#L35) of [`react-native-screens`](https://github.com/software-mansion/react-native-screens) library rely on `RCTInvalidating#invalidate` method being called in adequate moment to release retained resources (in my case the `RNSScreenView` holds a strong reference to it's view controller preventing it from being garbage collected). However in case of brownfield applications (React Native is used only for a particular view & loaded on demand, see: software-mansion/react-native-screens#1754 for discussion & app example) when view controller holding `RCTRootView` is dismissed and whole `React Native` managed view / controller tree gets deallocated, `RCTInvalidating#invalidate` method is not called on the dismissed components, thus in my particular use case, leading to memory leak. Right now I've added call to `RCTUIManager#_purgeChildren:fromRegistry:` (which internally invalidates all components which implement `RCTInvalidating`) in `RCTUIManager#invalidate`. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [IOS][FIXED] - Purge children from view registry on `RCTUIManager` invalidation. Pull Request resolved: #38617 Test Plan: You can run the [demo](https://github.com/mkondakov/RNSScreensMemoryLeak) provided in the [issue](software-mansion/react-native-screens#1754). Following screenshots show that memory leak in brownfield application is resolved. Without the change (`invalidate` method is not being called on native components)  With the change:  Reviewed By: NickGerleman Differential Revision: D49952215 Pulled By: javache fbshipit-source-id: 6336b86774615acc40279c97e6ae0bb777bda8ad
My patch was just recently picked into RN, and AFAIK it will be available with react-native |
Description
Instance of RNSScreen class creates strong reference cycle with instance of RNSScreenView class. This issue is critical in our project where user can open and close react-native app inside native iOS app many times.
Steps to reproduce
Snack or a link to a repository
https://github.com/mkondakov/RNSScreensMemoryLeak
Screens version
3.20.0
React Native version
0.71.6
Platforms
iOS
JavaScript runtime
None
Workflow
React Native (without Expo)
Architecture
None
Build type
Release mode
Device
Real device
Device model
all models
Acknowledgements
Yes
The text was updated successfully, but these errors were encountered: