mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-11 09:11:14 +08:00
Trigger GC and drop compiled code on low memory
Reviewed By: astreet Differential Revision: D2658693 fb-gh-sync-id: 8cba49b67ac45a2dbf8b4c9c404d6fb9c97693f6
This commit is contained in:
committed by
facebook-github-bot-5
parent
611e0619ca
commit
510d50fc17
@@ -0,0 +1,93 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentCallbacks2;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
|
||||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.MemoryPressure;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
|
||||
import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
|
||||
import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE;
|
||||
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
|
||||
|
||||
/**
|
||||
* Translates and routes memory pressure events to the current catalyst instance.
|
||||
*/
|
||||
public class MemoryPressureRouter {
|
||||
// Trigger this by sending an intent to your activity with adb shell:
|
||||
// am start -a "com.facebook.catalyst.ACTION_TRIM_MEMORY" --activity-single-top -n <activity>
|
||||
private static final String ACTION_TRIM_MEMORY ="com.facebook.catalyst.ACTION_TRIM_MEMORY";
|
||||
|
||||
private @Nullable CatalystInstance mCatalystInstance;
|
||||
private final ComponentCallbacks2 mCallbacks = new ComponentCallbacks2() {
|
||||
@Override
|
||||
public void onTrimMemory(int level) {
|
||||
trimMemory(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
}
|
||||
};
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
public static boolean handleDebugIntent(Activity activity, String action) {
|
||||
switch (action) {
|
||||
case ACTION_TRIM_MEMORY:
|
||||
simulateTrimMemory(activity, TRIM_MEMORY_MODERATE);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryPressureRouter(Context context) {
|
||||
context.getApplicationContext().registerComponentCallbacks(mCallbacks);
|
||||
}
|
||||
|
||||
public void onNewReactContextCreated(ReactContext reactContext) {
|
||||
mCatalystInstance = reactContext.getCatalystInstance();
|
||||
}
|
||||
|
||||
public void onReactInstanceDestroyed() {
|
||||
mCatalystInstance = null;
|
||||
}
|
||||
|
||||
public void destroy(Context context) {
|
||||
context.getApplicationContext().unregisterComponentCallbacks(mCallbacks);
|
||||
}
|
||||
|
||||
private void trimMemory(int level) {
|
||||
if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
|
||||
dispatchMemoryPressure(MemoryPressure.CRITICAL);
|
||||
} else if (level >= TRIM_MEMORY_BACKGROUND || level == TRIM_MEMORY_RUNNING_CRITICAL) {
|
||||
dispatchMemoryPressure(MemoryPressure.MODERATE);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchMemoryPressure(MemoryPressure level) {
|
||||
if (mCatalystInstance != null) {
|
||||
mCatalystInstance.handleMemoryPressure(level);
|
||||
}
|
||||
}
|
||||
|
||||
private static void simulateTrimMemory(Activity activity, int level) {
|
||||
activity.getApplication().onTrimMemory(level);
|
||||
activity.onTrimMemory(level);
|
||||
}
|
||||
}
|
||||
@@ -100,6 +100,7 @@ import com.facebook.systrace.Systrace;
|
||||
new ConcurrentLinkedQueue<>();
|
||||
private volatile boolean mHasStartedCreatingInitialContext = false;
|
||||
private final UIImplementationProvider mUIImplementationProvider;
|
||||
private final MemoryPressureRouter mMemoryPressureRouter;
|
||||
|
||||
private final ReactInstanceDevCommandsHandler mDevInterface =
|
||||
new ReactInstanceDevCommandsHandler() {
|
||||
@@ -215,6 +216,7 @@ import com.facebook.systrace.Systrace;
|
||||
mBridgeIdleDebugListener = bridgeIdleDebugListener;
|
||||
mLifecycleState = initialLifecycleState;
|
||||
mUIImplementationProvider = uiImplementationProvider;
|
||||
mMemoryPressureRouter = new MemoryPressureRouter(applicationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -400,6 +402,7 @@ import com.facebook.systrace.Systrace;
|
||||
public void onDestroy() {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
mMemoryPressureRouter.destroy(mApplicationContext);
|
||||
if (mUseDeveloperSupport) {
|
||||
mDevSupportManager.setDevSupportEnabled(false);
|
||||
}
|
||||
@@ -539,6 +542,7 @@ import com.facebook.systrace.Systrace;
|
||||
|
||||
catalystInstance.initialize();
|
||||
mDevSupportManager.onNewReactContextCreated(reactContext);
|
||||
mMemoryPressureRouter.onNewReactContextCreated(reactContext);
|
||||
moveReactContextToCurrentLifecycleState(reactContext);
|
||||
|
||||
for (ReactRootView rootView : mAttachedRootViews) {
|
||||
@@ -591,6 +595,7 @@ import com.facebook.systrace.Systrace;
|
||||
}
|
||||
reactContext.onDestroy();
|
||||
mDevSupportManager.onReactInstanceDestroyed(reactContext);
|
||||
mMemoryPressureRouter.onReactInstanceDestroyed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.facebook.react.bridge.queue.CatalystQueueConfiguration;
|
||||
@@ -49,6 +47,8 @@ public interface CatalystInstance {
|
||||
<T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface);
|
||||
Collection<NativeModule> getNativeModules();
|
||||
|
||||
void handleMemoryPressure(MemoryPressure level);
|
||||
|
||||
/**
|
||||
* Adds a idle listener for this Catalyst instance. The listener will receive notifications
|
||||
* whenever the bridge transitions from idle to busy and vice-versa, where the busy state is
|
||||
|
||||
@@ -314,6 +314,11 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
return mJavaRegistry.getAllModules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMemoryPressure(MemoryPressure level) {
|
||||
Assertions.assertNotNull(mBridge).handleMemoryPressure(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a idle listener for this Catalyst instance. The listener will receive notifications
|
||||
* whenever the bridge transitions from idle to busy and vice-versa, where the busy state is
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
public enum MemoryPressure {
|
||||
MODERATE,
|
||||
CRITICAL
|
||||
}
|
||||
@@ -56,6 +56,19 @@ public class ReactBridge extends Countable {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public void handleMemoryPressure(MemoryPressure level) {
|
||||
switch (level) {
|
||||
case MODERATE:
|
||||
handleMemoryPressureModerate();
|
||||
break;
|
||||
case CRITICAL:
|
||||
handleMemoryPressureCritical();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown level: " + level);
|
||||
}
|
||||
}
|
||||
|
||||
private native void initialize(
|
||||
JavaScriptExecutor jsExecutor,
|
||||
ReactCallback callback,
|
||||
@@ -72,4 +85,6 @@ public class ReactBridge extends Countable {
|
||||
public native boolean supportsProfiling();
|
||||
public native void startProfiler(String title);
|
||||
public native void stopProfiler(String title, String filename);
|
||||
private native void handleMemoryPressureModerate();
|
||||
private native void handleMemoryPressureCritical();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user