Merge "Do not proactively kill cached/empty processes post boot" into tm-dev

This commit is contained in:
Makoto Onuki
2022-03-04 19:48:52 +00:00
committed by Android (Google) Code Review
4 changed files with 124 additions and 8 deletions

View File

@@ -650,6 +650,38 @@ final class ActivityManagerConstants extends ContentObserver {
// initialized in the constructor. // initialized in the constructor.
public int CUR_MAX_EMPTY_PROCESSES; public int CUR_MAX_EMPTY_PROCESSES;
/** @see #mNoKillCachedProcessesUntilBootCompleted */
private static final String KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED =
"no_kill_cached_processes_until_boot_completed";
/** @see #mNoKillCachedProcessesPostBootCompletedDurationMillis */
private static final String KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS =
"no_kill_cached_processes_post_boot_completed_duration_millis";
/** @see #mNoKillCachedProcessesUntilBootCompleted */
private static final boolean DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED = false;
/** @see #mNoKillCachedProcessesPostBootCompletedDurationMillis */
private static final long
DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS = 0;
/**
* If true, do not kill excessive cached processes proactively, until user-0 is unlocked.
* @see #mNoKillCachedProcessesPostBootCompletedDurationMillis
*/
volatile boolean mNoKillCachedProcessesUntilBootCompleted =
DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED;
/**
* Do not kill excessive cached processes proactively, for this duration after each user is
* unlocked.
* Note we don't proactively kill extra cached processes after this. The next oomadjuster pass
* will naturally do it.
*/
volatile long mNoKillCachedProcessesPostBootCompletedDurationMillis =
DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS;
// The number of empty apps at which we don't consider it necessary to do // The number of empty apps at which we don't consider it necessary to do
// memory trimming. // memory trimming.
public int CUR_TRIM_EMPTY_PROCESSES = computeEmptyProcessLimit(MAX_CACHED_PROCESSES) / 2; public int CUR_TRIM_EMPTY_PROCESSES = computeEmptyProcessLimit(MAX_CACHED_PROCESSES) / 2;
@@ -659,6 +691,14 @@ final class ActivityManagerConstants extends ContentObserver {
public int CUR_TRIM_CACHED_PROCESSES = public int CUR_TRIM_CACHED_PROCESSES =
(MAX_CACHED_PROCESSES - computeEmptyProcessLimit(MAX_CACHED_PROCESSES)) / 3; (MAX_CACHED_PROCESSES - computeEmptyProcessLimit(MAX_CACHED_PROCESSES)) / 3;
/** @see #mNoKillCachedProcessesUntilBootCompleted */
private static final String KEY_MAX_EMPTY_TIME_MILLIS =
"max_empty_time_millis";
private static final long DEFAULT_MAX_EMPTY_TIME_MILLIS = 30 * 60 * 1000;
volatile long mMaxEmptyTimeMillis = DEFAULT_MAX_EMPTY_TIME_MILLIS;
/** /**
* Packages that can't be killed even if it's requested to be killed on imperceptible. * Packages that can't be killed even if it's requested to be killed on imperceptible.
*/ */
@@ -869,6 +909,15 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_DEFER_BOOT_COMPLETED_BROADCAST: case KEY_DEFER_BOOT_COMPLETED_BROADCAST:
updateDeferBootCompletedBroadcast(); updateDeferBootCompletedBroadcast();
break; break;
case KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED:
updateNoKillCachedProcessesUntilBootCompleted();
break;
case KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS:
updateNoKillCachedProcessesPostBootCompletedDurationMillis();
break;
case KEY_MAX_EMPTY_TIME_MILLIS:
updateMaxEmptyTimeMillis();
break;
default: default:
break; break;
} }
@@ -1288,6 +1337,27 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST); DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST);
} }
private void updateNoKillCachedProcessesUntilBootCompleted() {
mNoKillCachedProcessesUntilBootCompleted = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED,
DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
}
private void updateNoKillCachedProcessesPostBootCompletedDurationMillis() {
mNoKillCachedProcessesPostBootCompletedDurationMillis = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS,
DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
}
private void updateMaxEmptyTimeMillis() {
mMaxEmptyTimeMillis = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_MAX_EMPTY_TIME_MILLIS,
DEFAULT_MAX_EMPTY_TIME_MILLIS);
}
private long[] parseLongArray(@NonNull String key, @NonNull long[] def) { private long[] parseLongArray(@NonNull String key, @NonNull long[] def) {
final String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, final String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
key, null); key, null);
@@ -1562,6 +1632,12 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mComponentAliasOverrides); pw.print("="); pw.println(mComponentAliasOverrides);
pw.print(" "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST); pw.print(" "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST);
pw.print("="); pw.println(mDeferBootCompletedBroadcast); pw.print("="); pw.println(mDeferBootCompletedBroadcast);
pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted);
pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
pw.print("="); pw.println(mNoKillCachedProcessesPostBootCompletedDurationMillis);
pw.print(" "); pw.print(KEY_MAX_EMPTY_TIME_MILLIS);
pw.print("="); pw.println(mMaxEmptyTimeMillis);
pw.println(); pw.println();
if (mOverrideMaxCachedProcesses >= 0) { if (mOverrideMaxCachedProcesses >= 0) {

View File

@@ -750,7 +750,7 @@ public class OomAdjuster {
} }
final long now = SystemClock.uptimeMillis(); final long now = SystemClock.uptimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime(); final long nowElapsed = SystemClock.elapsedRealtime();
final long oldTime = now - ProcessList.MAX_EMPTY_TIME; final long oldTime = now - mConstants.mMaxEmptyTimeMillis;
final boolean fullUpdate = processes == null; final boolean fullUpdate = processes == null;
ActiveUids activeUids = uids; ActiveUids activeUids = uids;
ArrayList<ProcessRecord> activeProcesses = fullUpdate ? mProcessList.getLruProcessesLOSP() ArrayList<ProcessRecord> activeProcesses = fullUpdate ? mProcessList.getLruProcessesLOSP()
@@ -1031,15 +1031,25 @@ public class OomAdjuster {
} }
} }
private long mNextNoKillDebugMessageTime;
@GuardedBy({"mService", "mProcLock"}) @GuardedBy({"mService", "mProcLock"})
private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed, private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed,
final long oldTime, final ActiveUids activeUids) { final long oldTime, final ActiveUids activeUids) {
ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP(); ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
final int numLru = lruList.size(); final int numLru = lruList.size();
final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now);
final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES if (!doKillExcessiveProcesses) {
- emptyProcessLimit; if (mNextNoKillDebugMessageTime < now) {
Slog.d(TAG, "Not killing cached processes"); // STOPSHIP Remove it b/222365734
mNextNoKillDebugMessageTime = now + 5000; // Every 5 seconds
}
}
final int emptyProcessLimit = doKillExcessiveProcesses
? mConstants.CUR_MAX_EMPTY_PROCESSES : Integer.MAX_VALUE;
final int cachedProcessLimit = doKillExcessiveProcesses
? (mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit) : Integer.MAX_VALUE;
int lastCachedGroup = 0; int lastCachedGroup = 0;
int lastCachedGroupUid = 0; int lastCachedGroupUid = 0;
int numCached = 0; int numCached = 0;
@@ -1089,7 +1099,7 @@ public class OomAdjuster {
case PROCESS_STATE_CACHED_EMPTY: case PROCESS_STATE_CACHED_EMPTY:
if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
&& app.getLastActivityTime() < oldTime) { && app.getLastActivityTime() < oldTime) {
app.killLocked("empty for " + ((oldTime + ProcessList.MAX_EMPTY_TIME app.killLocked("empty for " + ((now
- app.getLastActivityTime()) / 1000) + "s", - app.getLastActivityTime()) / 1000) + "s",
"empty for too long", "empty for too long",
ApplicationExitInfo.REASON_OTHER, ApplicationExitInfo.REASON_OTHER,
@@ -1258,6 +1268,25 @@ public class OomAdjuster {
} }
} }
/**
* Return true if we should kill excessive cached/empty processes.
*/
private boolean shouldKillExcessiveProcesses(long nowUptime) {
final long lastUserUnlockingUptime = mService.mUserController.getLastUserUnlockingUptime();
if (lastUserUnlockingUptime == 0) {
// No users have been unlocked.
return !mConstants.mNoKillCachedProcessesUntilBootCompleted;
}
final long noKillCachedProcessesPostBootCompletedDurationMillis =
mConstants.mNoKillCachedProcessesPostBootCompletedDurationMillis;
if ((lastUserUnlockingUptime + noKillCachedProcessesPostBootCompletedDurationMillis)
> nowUptime) {
return false;
}
return true;
}
private final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback = private final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback =
new ComputeOomAdjWindowCallback(); new ComputeOomAdjWindowCallback();

View File

@@ -293,9 +293,6 @@ public final class ProcessList {
// without empty apps being able to push them out of memory. // without empty apps being able to push them out of memory.
static final int MIN_CACHED_APPS = 2; static final int MIN_CACHED_APPS = 2;
// We allow empty processes to stick around for at most 30 minutes.
static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
// Threshold of number of cached+empty where we consider memory critical. // Threshold of number of cached+empty where we consider memory critical.
static final int TRIM_CRITICAL_THRESHOLD = 3; static final int TRIM_CRITICAL_THRESHOLD = 3;

View File

@@ -399,6 +399,9 @@ class UserController implements Handler.Callback {
@GuardedBy("mLock") @GuardedBy("mLock")
private @StopUserOnSwitch int mStopUserOnSwitch = STOP_USER_ON_SWITCH_DEFAULT; private @StopUserOnSwitch int mStopUserOnSwitch = STOP_USER_ON_SWITCH_DEFAULT;
/** @see #getLastUserUnlockingUptime */
private volatile long mLastUserUnlockingUptime = 0;
UserController(ActivityManagerService service) { UserController(ActivityManagerService service) {
this(new Injector(service)); this(new Injector(service));
} }
@@ -661,6 +664,8 @@ class UserController implements Handler.Callback {
uss.mUnlockProgress.setProgress(20); uss.mUnlockProgress.setProgress(20);
mLastUserUnlockingUptime = SystemClock.uptimeMillis();
// Dispatch unlocked to system services; when fully dispatched, // Dispatch unlocked to system services; when fully dispatched,
// that calls through to the next "unlocked" phase // that calls through to the next "unlocked" phase
mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget(); mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
@@ -2753,6 +2758,7 @@ class UserController implements Handler.Callback {
if (mSwitchingToSystemUserMessage != null) { if (mSwitchingToSystemUserMessage != null) {
pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage); pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage);
} }
pw.println(" mLastUserUnlockingUptime:" + mLastUserUnlockingUptime);
} }
} }
@@ -3077,6 +3083,14 @@ class UserController implements Handler.Callback {
return bOptions; return bOptions;
} }
/**
* Uptime when any user was being unlocked most recently. 0 if no users have been unlocked
* yet. To avoid lock contention (since it's used by OomAdjuster), it's volatile internally.
*/
public long getLastUserUnlockingUptime() {
return mLastUserUnlockingUptime;
}
/** /**
* Helper class to store user journey and session id. * Helper class to store user journey and session id.
* *