Merge "Apply correct memory trim levels for processes in LRU list"
This commit is contained in:
@@ -340,6 +340,7 @@ import com.android.server.SystemServiceManager;
|
||||
import com.android.server.ThreadPriorityBooster;
|
||||
import com.android.server.UserspaceRebootLogger;
|
||||
import com.android.server.Watchdog;
|
||||
import com.android.server.am.LowMemDetector.MemFactor;
|
||||
import com.android.server.appop.AppOpsService;
|
||||
import com.android.server.compat.PlatformCompat;
|
||||
import com.android.server.contentcapture.ContentCaptureManagerInternal;
|
||||
@@ -8224,13 +8225,25 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMemoryTrimLevel() {
|
||||
public @MemFactor int getMemoryTrimLevel() {
|
||||
enforceNotIsolatedCaller("getMyMemoryState");
|
||||
synchronized (this) {
|
||||
return mAppProfiler.getLastMemoryLevelLocked();
|
||||
}
|
||||
}
|
||||
|
||||
void setMemFactorOverride(@MemFactor int level) {
|
||||
synchronized (this) {
|
||||
if (level == mAppProfiler.getLastMemoryLevelLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAppProfiler.setMemFactorOverrideLocked(level);
|
||||
// Kick off an oom adj update since we forced a mem factor update.
|
||||
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShellCommand(FileDescriptor in, FileDescriptor out,
|
||||
FileDescriptor err, String[] args, ShellCallback callback,
|
||||
|
||||
@@ -25,6 +25,12 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL;
|
||||
import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityTaskManager;
|
||||
@@ -92,6 +98,7 @@ import android.view.Display;
|
||||
import com.android.internal.compat.CompatibilityChangeConfig;
|
||||
import com.android.internal.util.HexDump;
|
||||
import com.android.internal.util.MemInfoReader;
|
||||
import com.android.server.am.LowMemDetector.MemFactor;
|
||||
import com.android.server.compat.PlatformCompat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@@ -309,6 +316,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
return runCompat(pw);
|
||||
case "refresh-settings-cache":
|
||||
return runRefreshSettingsCache();
|
||||
case "memory-factor":
|
||||
return runMemoryFactor(pw);
|
||||
default:
|
||||
return handleDefaultCommands(cmd);
|
||||
}
|
||||
@@ -3014,6 +3023,81 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int runSetMemoryFactor(PrintWriter pw) throws RemoteException {
|
||||
final String levelArg = getNextArgRequired();
|
||||
@MemFactor int level = ADJ_MEM_FACTOR_NOTHING;
|
||||
switch (levelArg) {
|
||||
case "NORMAL":
|
||||
level = ADJ_MEM_FACTOR_NORMAL;
|
||||
break;
|
||||
case "MODERATE":
|
||||
level = ADJ_MEM_FACTOR_MODERATE;
|
||||
break;
|
||||
case "LOW":
|
||||
level = ADJ_MEM_FACTOR_LOW;
|
||||
break;
|
||||
case "CRITICAL":
|
||||
level = ADJ_MEM_FACTOR_CRITICAL;
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
level = Integer.parseInt(levelArg);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
if (level < ADJ_MEM_FACTOR_NORMAL || level > ADJ_MEM_FACTOR_CRITICAL) {
|
||||
getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
mInternal.setMemFactorOverride(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runShowMemoryFactor(PrintWriter pw) throws RemoteException {
|
||||
final @MemFactor int level = mInternal.getMemoryTrimLevel();
|
||||
switch (level) {
|
||||
case ADJ_MEM_FACTOR_NOTHING:
|
||||
pw.println("<UNKNOWN>");
|
||||
break;
|
||||
case ADJ_MEM_FACTOR_NORMAL:
|
||||
pw.println("NORMAL");
|
||||
break;
|
||||
case ADJ_MEM_FACTOR_MODERATE:
|
||||
pw.println("MODERATE");
|
||||
break;
|
||||
case ADJ_MEM_FACTOR_LOW:
|
||||
pw.println("LOW");
|
||||
break;
|
||||
case ADJ_MEM_FACTOR_CRITICAL:
|
||||
pw.println("CRITICAL");
|
||||
break;
|
||||
}
|
||||
pw.flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runResetMemoryFactor(PrintWriter pw) throws RemoteException {
|
||||
mInternal.setMemFactorOverride(ADJ_MEM_FACTOR_NOTHING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runMemoryFactor(PrintWriter pw) throws RemoteException {
|
||||
mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
|
||||
"runMemoryFactor()");
|
||||
|
||||
final String op = getNextArgRequired();
|
||||
switch (op) {
|
||||
case "set":
|
||||
return runSetMemoryFactor(pw);
|
||||
case "show":
|
||||
return runShowMemoryFactor(pw);
|
||||
case "reset":
|
||||
return runResetMemoryFactor(pw);
|
||||
default:
|
||||
getErrPrintWriter().println("Error: unknown command '" + op + "'");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private Resources getResources(PrintWriter pw) throws RemoteException {
|
||||
// system resources does not contain all the device configuration, construct it manually.
|
||||
@@ -3334,6 +3418,13 @@ final class ActivityManagerShellCommand extends ShellCommand {
|
||||
pw.println(" Removes all existing overrides for all changes for ");
|
||||
pw.println(" <PACKAGE_NAME> (back to default behaviour).");
|
||||
pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect).");
|
||||
pw.println(" memory-factor [command] [...]: sub-commands for overriding memory pressure factor");
|
||||
pw.println(" set <NORMAL|MODERATE|LOW|CRITICAL>");
|
||||
pw.println(" Overrides memory pressure factor. May also supply a raw int level");
|
||||
pw.println(" show");
|
||||
pw.println(" Shows the existing memory pressure factor");
|
||||
pw.println(" reset");
|
||||
pw.println(" Removes existing override for memory pressure factor");
|
||||
pw.println();
|
||||
Intent.printIntentArgsHelp(pw, "");
|
||||
}
|
||||
|
||||
@@ -20,11 +20,16 @@ import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
|
||||
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
|
||||
import static android.os.Process.FIRST_APPLICATION_UID;
|
||||
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING;
|
||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
|
||||
|
||||
import android.annotation.BroadcastBehavior;
|
||||
@@ -72,6 +77,7 @@ import com.android.internal.os.ProcessCpuTracker;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.internal.util.MemInfoReader;
|
||||
import com.android.server.am.LowMemDetector.MemFactor;
|
||||
import com.android.server.am.ProcessList.ProcStateMemTracker;
|
||||
import com.android.server.utils.PriorityDump;
|
||||
|
||||
@@ -202,7 +208,10 @@ public class AppProfiler {
|
||||
* processes are going away for other reasons.
|
||||
*/
|
||||
@GuardedBy("mService")
|
||||
private int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
|
||||
private @MemFactor int mLastMemoryLevel = ADJ_MEM_FACTOR_NORMAL;
|
||||
|
||||
@GuardedBy("mService")
|
||||
private @MemFactor int mMemFactorOverride = ADJ_MEM_FACTOR_NOTHING;
|
||||
|
||||
/**
|
||||
* The last total number of process we have, to determine if changes actually look
|
||||
@@ -851,7 +860,7 @@ public class AppProfiler {
|
||||
|
||||
@GuardedBy("mService")
|
||||
boolean isLastMemoryLevelNormal() {
|
||||
return mLastMemoryLevel <= ProcessStats.ADJ_MEM_FACTOR_NORMAL;
|
||||
return mLastMemoryLevel <= ADJ_MEM_FACTOR_NORMAL;
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
@@ -867,6 +876,11 @@ public class AppProfiler {
|
||||
mAllowLowerMemLevel = allowLowerMemLevel;
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
void setMemFactorOverrideLocked(@MemFactor int factor) {
|
||||
mMemFactorOverride = factor;
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
boolean updateLowMemStateLocked(int numCached, int numEmpty, int numTrimming) {
|
||||
final int numOfLru = mService.mProcessList.getLruSizeLocked();
|
||||
@@ -885,28 +899,32 @@ public class AppProfiler {
|
||||
&& numEmpty <= mService.mConstants.CUR_TRIM_EMPTY_PROCESSES) {
|
||||
final int numCachedAndEmpty = numCached + numEmpty;
|
||||
if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
|
||||
memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
|
||||
memFactor = ADJ_MEM_FACTOR_CRITICAL;
|
||||
} else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
|
||||
memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
|
||||
memFactor = ADJ_MEM_FACTOR_LOW;
|
||||
} else {
|
||||
memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
|
||||
memFactor = ADJ_MEM_FACTOR_MODERATE;
|
||||
}
|
||||
} else {
|
||||
memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
|
||||
memFactor = ADJ_MEM_FACTOR_NORMAL;
|
||||
}
|
||||
}
|
||||
// We always allow the memory level to go up (better). We only allow it to go
|
||||
// down if we are in a state where that is allowed, *and* the total number of processes
|
||||
// has gone down since last time.
|
||||
if (DEBUG_OOM_ADJ) {
|
||||
Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
|
||||
Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor + " override=" + mMemFactorOverride
|
||||
+ " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
|
||||
+ " numProcs=" + mService.mProcessList.getLruSizeLocked()
|
||||
+ " last=" + mLastNumProcesses);
|
||||
}
|
||||
boolean override;
|
||||
if (override = (mMemFactorOverride != ADJ_MEM_FACTOR_NOTHING)) {
|
||||
memFactor = mMemFactorOverride;
|
||||
}
|
||||
if (memFactor > mLastMemoryLevel) {
|
||||
if (!mAllowLowerMemLevel
|
||||
|| mService.mProcessList.getLruSizeLocked() >= mLastNumProcesses) {
|
||||
if (!override && (!mAllowLowerMemLevel
|
||||
|| mService.mProcessList.getLruSizeLocked() >= mLastNumProcesses)) {
|
||||
memFactor = mLastMemoryLevel;
|
||||
if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
|
||||
}
|
||||
@@ -924,17 +942,17 @@ public class AppProfiler {
|
||||
mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(), now);
|
||||
trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
|
||||
}
|
||||
if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
|
||||
if (memFactor != ADJ_MEM_FACTOR_NORMAL) {
|
||||
if (mLowRamStartTime == 0) {
|
||||
mLowRamStartTime = now;
|
||||
}
|
||||
int step = 0;
|
||||
int fgTrimLevel;
|
||||
switch (memFactor) {
|
||||
case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
|
||||
case ADJ_MEM_FACTOR_CRITICAL:
|
||||
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
|
||||
break;
|
||||
case ProcessStats.ADJ_MEM_FACTOR_LOW:
|
||||
case ADJ_MEM_FACTOR_LOW:
|
||||
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
|
||||
break;
|
||||
default:
|
||||
@@ -947,7 +965,7 @@ public class AppProfiler {
|
||||
if (mService.mAtmInternal.getPreviousProcess() != null) minFactor++;
|
||||
if (factor < minFactor) factor = minFactor;
|
||||
int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
|
||||
for (int i = numOfLru - 1; i >= 0; i--) {
|
||||
for (int i = 0; i < numOfLru; i++) {
|
||||
ProcessRecord app = mService.mProcessList.mLruProcesses.get(i);
|
||||
if (allChanged || app.procStateChanged) {
|
||||
mService.setProcessTrackerStateLocked(app, trackerMemFactor, now);
|
||||
@@ -1032,7 +1050,7 @@ public class AppProfiler {
|
||||
mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
|
||||
mLowRamStartTime = 0;
|
||||
}
|
||||
for (int i = numOfLru - 1; i >= 0; i--) {
|
||||
for (int i = 0; i < numOfLru; i++) {
|
||||
ProcessRecord app = mService.mProcessList.mLruProcesses.get(i);
|
||||
if (allChanged || app.procStateChanged) {
|
||||
mService.setProcessTrackerStateLocked(app, trackerMemFactor, now);
|
||||
@@ -1622,16 +1640,16 @@ public class AppProfiler {
|
||||
@GuardedBy("mService")
|
||||
void dumpLastMemoryLevelLocked(PrintWriter pw) {
|
||||
switch (mLastMemoryLevel) {
|
||||
case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
|
||||
case ADJ_MEM_FACTOR_NORMAL:
|
||||
pw.println("normal)");
|
||||
break;
|
||||
case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
|
||||
case ADJ_MEM_FACTOR_MODERATE:
|
||||
pw.println("moderate)");
|
||||
break;
|
||||
case ProcessStats.ADJ_MEM_FACTOR_LOW:
|
||||
case ADJ_MEM_FACTOR_LOW:
|
||||
pw.println("low)");
|
||||
break;
|
||||
case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
|
||||
case ADJ_MEM_FACTOR_CRITICAL:
|
||||
pw.println("critical)");
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -16,8 +16,19 @@
|
||||
|
||||
package com.android.server.am;
|
||||
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL;
|
||||
import static com.android.internal.app.procstats.ProcessStats.ADJ_NOTHING;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Detects low memory using PSI.
|
||||
*
|
||||
@@ -32,13 +43,20 @@ public final class LowMemDetector {
|
||||
private final Object mPressureStateLock = new Object();
|
||||
|
||||
@GuardedBy("mPressureStateLock")
|
||||
private int mPressureState = MEM_PRESSURE_NONE;
|
||||
private int mPressureState = ADJ_MEM_FACTOR_NORMAL;
|
||||
|
||||
public static final int ADJ_MEM_FACTOR_NOTHING = ADJ_NOTHING;
|
||||
|
||||
/* getPressureState return values */
|
||||
public static final int MEM_PRESSURE_NONE = 0;
|
||||
public static final int MEM_PRESSURE_LOW = 1;
|
||||
public static final int MEM_PRESSURE_MEDIUM = 2;
|
||||
public static final int MEM_PRESSURE_HIGH = 3;
|
||||
@IntDef(prefix = { "ADJ_MEM_FACTOR_" }, value = {
|
||||
ADJ_MEM_FACTOR_NOTHING,
|
||||
ADJ_MEM_FACTOR_NORMAL,
|
||||
ADJ_MEM_FACTOR_MODERATE,
|
||||
ADJ_MEM_FACTOR_LOW,
|
||||
ADJ_MEM_FACTOR_CRITICAL,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface MemFactor{}
|
||||
|
||||
LowMemDetector(ActivityManagerService am) {
|
||||
mAm = am;
|
||||
@@ -62,7 +80,7 @@ public final class LowMemDetector {
|
||||
* there should be conversion performed here to translate pressure state
|
||||
* into memFactor.
|
||||
*/
|
||||
public int getMemFactor() {
|
||||
public @MemFactor int getMemFactor() {
|
||||
synchronized (mPressureStateLock) {
|
||||
return mPressureState;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user