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

Android memory leak due to JSC #23259

Closed
ben-manes opened this issue Feb 2, 2019 · 11 comments
Closed

Android memory leak due to JSC #23259

ben-manes opened this issue Feb 2, 2019 · 11 comments
Labels
Bug Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: Android Android applications. Resolution: Locked This issue was locked by the bot.

Comments

@ben-manes
Copy link
Contributor

I apologize for not providing this report sooner or with detailed charts. We have been using a patched version of JSC for a few months now and believe RN should drive its resolution. I did not investigate or resolve it, but the author prefers to remain anonymous and uninvolved. The provided patch had a significant impact for a long running application on a low end device.

Environment

This occurs on all versions of Android and RN. It requires patching JavaScript Core and using that version.

Description

A full GC is performed only when Heap#overCriticalMemoryThreshold returns true or if the default is changed to disable the generational GC. Otherwise only the young generation is collected. Unfortunately, overCriticalMemoryThreshold is only implemented for iOS and always returns false for other platforms. This means that any objects promoted from young to old are not GC'd and the app will eventually crash due to an out of memory error.

Please note that running RN through the Chrome debugger does not use JSC. This will use Chrome's JS engine and promptly reclaim memory. We confirmed this bug and fix by reducing the maximum memory for JSC, observing the leak, and then healthy behavior when resolved.

Patch

The least invasive change was to force a full collection and we are satisfied with the resulting performance. In our application, we did not experience long pause times that would result in a negative experience. We changed overCriticalMemoryThreshold to return true on non-iOS platforms and believe that is the correct default behavior. A more advanced solution would be to add Android support to calculate if the threshold was crossed.

iff --git a/webkit/Source/JavaScriptCore/heap/Heap.cpp b/webkit/Source/JavaScriptCore/heap/Heap.cpp
index ffeac67d..9dcf4113 100644
--- a/webkit/Source/JavaScriptCore/heap/Heap.cpp
+++ b/webkit/Source/JavaScriptCore/heap/Heap.cpp
@@ -498,7 +498,7 @@ bool Heap::overCriticalMemoryThreshold(MemoryThresholdCallType memoryThresholdCa
     return m_overCriticalMemoryThreshold;
 #else
     UNUSED_PARAM(memoryThresholdCallType);
-    return false;
+    return true;
 #endif
 }

Resolution

We would not be the appropriate party to coordinate a long term fix. If we went to JSC directly, RN would still have to upgrade its dependency (4yrs old, iirc). Please drive this issue to a happy conclusion.

@react-native-bot react-native-bot added the Platform: Android Android applications. label Feb 2, 2019
@react-native-bot

This comment has been minimized.

@hramos
Copy link
Contributor

hramos commented Feb 2, 2019

The JSC dependency was updated back in December (f3e5cce), and is scheduled to be part of the 0.59 release. Can you verify if the issue is present in the updated JSC?

@ben-manes
Copy link
Contributor Author

ben-manes commented Feb 2, 2019

Yes, the linked code is for the latest version of JSC. When investigating this issue, we tried upgrading to the latest when discovering it was a JS GC issue, but not knowing the cause. Our custom version of JSC was built (& up to date) on Dec 18, 2018 when we moved to bintray rather than relying on locally built copies for the deployment process.

@akshetpandey
Copy link

@hramos: Can we remove the Old Version tag. This impacts the version of JSC bundled in master and is likely a blocker for 0.59 release.

Here is the JSC code as compiled on master:

https://trac.webkit.org/browser/webkit/releases/WebKitGTK/webkit-2.22.2/Source/JavaScriptCore/heap/Heap.cpp#L516

Latest stable release also doesn't have it implemented:

https://trac.webkit.org/browser/webkit/releases/WebKitGTK/webkit-2.23.3/Source/JavaScriptCore/heap/Heap.cpp#L516

@akshetpandey
Copy link

akshetpandey commented Feb 4, 2019

As far as I can tell, the version of JS bundled with react native before the JSC upgrade doesn't have this problem, but all versions of npm/jsc-android after 224109.0.0 does have this problem. Which would imply expo also has this issue.

@akshetpandey
Copy link

@ben-manes
Copy link
Contributor Author

@akshetpandey why would the bundled JS not have this problem? Does 0.59 replace JSC with a different implementation or by chance disable generational GC?

|    +--- com.facebook.react:react-native:+ -> 0.58.3
|    ...
|    \--- org.webkit:android-jsc:r174650 -> com.withvector:android-jsc:r225067

I'll create the issue over there and cc you.

@akshetpandey
Copy link

Sorry, I meant the version before JSC was upgraded.

@ben-manes
Copy link
Contributor Author

We found this problem in 0.53 and are currently upgrading to 0.58.3. We were using the stock JSC and tried upgrading via jsc-android-buildscripts when debugging. It appeared to us to be a long standing issue from the webkit commit history.

@kelset kelset added Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. and removed Resolution: Missing Environment Info labels Feb 5, 2019
@hramos hramos removed the Bug Report label Feb 6, 2019
@guhungry
Copy link
Contributor

guhungry commented Feb 27, 2019

@ben-manes According to react-native-community/jsc-android-buildscripts#82 (comment). I think this issue can be closed?

@ben-manes
Copy link
Contributor Author

Okay

@facebook facebook locked as resolved and limited conversation to collaborators Feb 27, 2020
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Feb 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Impact: Regression Describes a behavior that used to work on a prior release, but stopped working recently. Platform: Android Android applications. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

6 participants