Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03bcb30a authored by Jing Ji's avatar Jing Ji Committed by Android (Google) Code Review
Browse files

Merge "Apply correct memory trim levels for processes in LRU list"

parents c95fd081 1ad98565
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -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,
+91 −0
Original line number Diff line number Diff line
@@ -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, "");
        }
+36 −18
Original line number Diff line number Diff line
@@ -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:
+24 −6
Original line number Diff line number Diff line
@@ -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;
        }