Loading services/core/java/com/android/server/am/ActivityManagerService.java +14 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading services/core/java/com/android/server/am/ActivityManagerShellCommand.java +91 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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. Loading Loading @@ -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, ""); } Loading services/core/java/com/android/server/am/AppProfiler.java +36 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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") Loading @@ -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(); Loading @@ -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!"); } Loading @@ -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: Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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: Loading services/core/java/com/android/server/am/LowMemDetector.java +24 −6 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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; Loading @@ -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; } Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +14 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +91 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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. Loading Loading @@ -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, ""); } Loading
services/core/java/com/android/server/am/AppProfiler.java +36 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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") Loading @@ -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(); Loading @@ -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!"); } Loading @@ -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: Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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: Loading
services/core/java/com/android/server/am/LowMemDetector.java +24 −6 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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; Loading @@ -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; } Loading