Skip to content

Commit

Permalink
feat: Trigger Java GC on reload (#43813)
Browse files Browse the repository at this point in the history
Summary:
While we (Margelo) were developing a new C++ 3D library for react-native, we noticed that Java often keeps a lot of dead instances in memory, making it hard to debug memory allocations (or actually _de_-allocations), especially since we use `jsi::HostObject` and `jni::HybridClass` in conjunction. Having two garbage-collected languages retain an object is a bit tricky, and making sure that we aren't doing anything wrong with our allocations and references was not easy - but manually calling `System.gc()` on app reloads helped us see that much better.

Before this, we needed to wait multiple minutes until some Java objects are actually freed from the GC. Our use-case was a `facebook::jni::HybridClass`, which was held strong in a `facebook::jsi::HostObject` (so again, two GC'd languages).

There _should_ be no change in behaviour with this PR, just two things to note:

1. Memory might be free'd more eagerly in full reloads (dev builds) - makes sense for library developers, especially when working with C++ modules.
2. `System.gc()` only _suggests_ garbage collection, it does not _force_ it. But when it runs, it might impact performance, although we haven't noticed any impact of that at all. The garbage collector runs anyways - better during a reload than later when exceuting the app normally.

## 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
-->

[ANDROID] [ADDED] - Trigger Java GC on app reload

Pull Request resolved: #43813

Test Plan:
Open an app, create a Java module that holds a few objects, add `finalize()` methods to those objects and log their deletion.

Reload the app to see the logs, compare before vs after.

Reviewed By: rshest

Differential Revision: D65418163

Pulled By: javache

fbshipit-source-id: 7597548790577dfc542b57f59578ae48df543b14
  • Loading branch information
mrousavy authored and facebook-github-bot committed Nov 4, 2024
1 parent e1a1cea commit de3c1ee
Showing 1 changed file with 8 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,14 @@ public void onReactInstanceDestroyed(ReactContext reactContext) {
// for this manager
resetCurrentContext(null);
}

// If some JNI types (e.g. jni::HybridClass) are used in JSI (e.g. jsi::HostObject), they might
// not be immediately deleted on an app refresh as both Java and JavaScript are
// garbage-collected languages and the memory might float around for a while. For C++
// developers, this will be hard to debug as destructors might be called at a later point, so in
// this case we trigger a Java GC to maybe eagerly collect such objects when the app
// reloads.
System.gc();
}

@Override
Expand Down

0 comments on commit de3c1ee

Please sign in to comment.