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.
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
// memory trimming.
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 =
(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.
*/
@@ -869,6 +909,15 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_DEFER_BOOT_COMPLETED_BROADCAST:
updateDeferBootCompletedBroadcast();
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:
break;
}
@@ -1288,6 +1337,27 @@ final class ActivityManagerConstants extends ContentObserver {
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) {
final String val = DeviceConfig.getString(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
key, null);
@@ -1562,6 +1632,12 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mComponentAliasOverrides);
pw.print(" "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST);
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();
if (mOverrideMaxCachedProcesses >= 0) {

View File

@@ -750,7 +750,7 @@ public class OomAdjuster {
}
final long now = SystemClock.uptimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
final long oldTime = now - mConstants.mMaxEmptyTimeMillis;
final boolean fullUpdate = processes == null;
ActiveUids activeUids = uids;
ArrayList<ProcessRecord> activeProcesses = fullUpdate ? mProcessList.getLruProcessesLOSP()
@@ -1031,15 +1031,25 @@ public class OomAdjuster {
}
}
private long mNextNoKillDebugMessageTime;
@GuardedBy({"mService", "mProcLock"})
private boolean updateAndTrimProcessLSP(final long now, final long nowElapsed,
final long oldTime, final ActiveUids activeUids) {
ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
final int numLru = lruList.size();
final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES
- emptyProcessLimit;
final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now);
if (!doKillExcessiveProcesses) {
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 lastCachedGroupUid = 0;
int numCached = 0;
@@ -1089,7 +1099,7 @@ public class OomAdjuster {
case PROCESS_STATE_CACHED_EMPTY:
if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
&& app.getLastActivityTime() < oldTime) {
app.killLocked("empty for " + ((oldTime + ProcessList.MAX_EMPTY_TIME
app.killLocked("empty for " + ((now
- app.getLastActivityTime()) / 1000) + "s",
"empty for too long",
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 =
new ComputeOomAdjWindowCallback();

View File

@@ -293,9 +293,6 @@ public final class ProcessList {
// without empty apps being able to push them out of memory.
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.
static final int TRIM_CRITICAL_THRESHOLD = 3;

View File

@@ -399,6 +399,9 @@ class UserController implements Handler.Callback {
@GuardedBy("mLock")
private @StopUserOnSwitch int mStopUserOnSwitch = STOP_USER_ON_SWITCH_DEFAULT;
/** @see #getLastUserUnlockingUptime */
private volatile long mLastUserUnlockingUptime = 0;
UserController(ActivityManagerService service) {
this(new Injector(service));
}
@@ -661,6 +664,8 @@ class UserController implements Handler.Callback {
uss.mUnlockProgress.setProgress(20);
mLastUserUnlockingUptime = SystemClock.uptimeMillis();
// Dispatch unlocked to system services; when fully dispatched,
// that calls through to the next "unlocked" phase
mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
@@ -2753,6 +2758,7 @@ class UserController implements Handler.Callback {
if (mSwitchingToSystemUserMessage != null) {
pw.println(" mSwitchingToSystemUserMessage: " + mSwitchingToSystemUserMessage);
}
pw.println(" mLastUserUnlockingUptime:" + mLastUserUnlockingUptime);
}
}
@@ -3077,6 +3083,14 @@ class UserController implements Handler.Callback {
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.
*