Reland OomAdjuster: demote previous process to cached after configurable timeout

Previous processes shouldn't stay out of cached indefinitely; they
should be eventually moved to cached and allowed to be restricted and
frozen. Add a configurable timeout to decide when the previous app
should move to cached.

The default timeout is 60s.

Reverts change bb195e7af6.

Bug: 261065790
Test: atest MockingOomAdjusterTests

Change-Id: I0494059976275cab309a5353bfef608da796bd2f
Merged-in: I0494059976275cab309a5353bfef608da796bd2f
This commit is contained in:
Tim Murray
2022-12-13 13:13:59 -08:00
parent 37ea5f6833
commit e22197994a
2 changed files with 44 additions and 16 deletions

View File

@@ -129,6 +129,7 @@ final class ActivityManagerConstants extends ContentObserver {
static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle"; static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE = "kill_bg_restricted_cached_idle";
static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME = static final String KEY_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME =
"kill_bg_restricted_cached_idle_settle_time"; "kill_bg_restricted_cached_idle_settle_time";
static final String KEY_MAX_PREVIOUS_TIME = "max_previous_time";
/** /**
* Note this key is on {@link DeviceConfig#NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS}. * Note this key is on {@link DeviceConfig#NAMESPACE_ACTIVITY_MANAGER_COMPONENT_ALIAS}.
* @see #mEnableComponentAlias * @see #mEnableComponentAlias
@@ -192,6 +193,7 @@ final class ActivityManagerConstants extends ContentObserver {
private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100% private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100%
private static final long DEFAULT_PROCESS_KILL_TIMEOUT_MS = 10 * 1000; private static final long DEFAULT_PROCESS_KILL_TIMEOUT_MS = 10 * 1000;
private static final long DEFAULT_NETWORK_ACCESS_TIMEOUT_MS = 200; // 0.2 sec private static final long DEFAULT_NETWORK_ACCESS_TIMEOUT_MS = 200; // 0.2 sec
private static final long DEFAULT_MAX_PREVIOUS_TIME = 60 * 1000; // 60s
static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000; static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000;
static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000; static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000;
@@ -534,6 +536,9 @@ final class ActivityManagerConstants extends ContentObserver {
public long TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION = public long TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION =
DEFAULT_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION; DEFAULT_TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION;
// How long a process can remain at previous oom_adj before dropping to cached
public static long MAX_PREVIOUS_TIME = DEFAULT_MAX_PREVIOUS_TIME;
/** /**
* The minimum time we allow between crashes, for us to consider this * The minimum time we allow between crashes, for us to consider this
* application to be bad and stop its services and reject broadcasts. * application to be bad and stop its services and reject broadcasts.
@@ -1171,6 +1176,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION: case KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION:
updateEnableWaitForFinishAttachApplication(); updateEnableWaitForFinishAttachApplication();
break; break;
case KEY_MAX_PREVIOUS_TIME:
updateMaxPreviousTime();
break;
default: default:
break; break;
} }
@@ -1825,6 +1833,7 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_LOW_SWAP_THRESHOLD_PERCENT); DEFAULT_LOW_SWAP_THRESHOLD_PERCENT);
} }
private void updateTopToFgsGraceDuration() { private void updateTopToFgsGraceDuration() {
TOP_TO_FGS_GRACE_DURATION = DeviceConfig.getLong( TOP_TO_FGS_GRACE_DURATION = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1832,6 +1841,13 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_TOP_TO_FGS_GRACE_DURATION); DEFAULT_TOP_TO_FGS_GRACE_DURATION);
} }
private void updateMaxPreviousTime() {
MAX_PREVIOUS_TIME = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_MAX_PREVIOUS_TIME,
DEFAULT_MAX_PREVIOUS_TIME);
}
private void updateMinAssocLogDuration() { private void updateMinAssocLogDuration() {
MIN_ASSOC_LOG_DURATION = DeviceConfig.getLong( MIN_ASSOC_LOG_DURATION = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MIN_ASSOC_LOG_DURATION, DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MIN_ASSOC_LOG_DURATION,

View File

@@ -2018,12 +2018,23 @@ public class OomAdjuster {
} }
} }
} }
if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) { if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) {
// This was the previous process that showed UI to the user. We want to
// try to keep it around more aggressively, to give a good experience
// around switching between two apps. However, we don't want to keep the
// process in this privileged state indefinitely. Eventually, allow the
// app to be demoted to cached.
if ((state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY
&& (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) < now)) {
procState = PROCESS_STATE_LAST_ACTIVITY;
schedGroup = SCHED_GROUP_BACKGROUND;
state.setAdjType("previous-expired");
adj = CACHED_APP_MIN_ADJ;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Expire prev adj: " + app);
}
} else {
if (adj > PREVIOUS_APP_ADJ) { if (adj > PREVIOUS_APP_ADJ) {
// This was the previous process that showed UI to the user.
// We want to try to keep it around more aggressively, to give
// a good experience around switching between two apps.
adj = PREVIOUS_APP_ADJ; adj = PREVIOUS_APP_ADJ;
schedGroup = SCHED_GROUP_BACKGROUND; schedGroup = SCHED_GROUP_BACKGROUND;
state.setCached(false); state.setCached(false);
@@ -2040,6 +2051,7 @@ public class OomAdjuster {
} }
} }
} }
}
if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
+ " reason=" + state.getAdjType()); + " reason=" + state.getAdjType());