Skip to content

Android memory leak due to JSC #23259

@ben-manes

Description

@ben-manes

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugImpact: RegressionDescribes a behavior that used to work on a prior release, but stopped working recently.Platform: AndroidAndroid applications.Resolution: LockedThis issue was locked by the bot.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions