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

Commit ed0a3220 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Further tuning of PSS collection.

We now keep track of a scaling factor of collection
for each memory state, and allow that to continually
grow as long as the process doesn't come back to it
from a new higher memory state.  This should allow us
to spread out the sample rate for longer-running processes
to be much longer, to reduce the frequency of PSS
collection.

Also moved the decision about when to do a PSS sample of
all processes from some internal timing in the activity
manager to being tied to procstats data commits.  This
makes the interval longer, and ensures after each commit
we have a good initial sample of memory data for all
processes.

Bug: 70859548
Test: atest CtsAppTestCases
Change-Id: Ia3ea2bc9e2d032d51e46e178e2b86b072af9f1ba
parent 27a6db48
Loading
Loading
Loading
Loading
+25 −19
Original line number Diff line number Diff line
@@ -1854,7 +1854,6 @@ public class ActivityManagerService extends IActivityManager.Stub
    static final int REPORT_MEM_USAGE_MSG = 33;
    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
    static final int PERSIST_URI_GRANTS_MSG = 38;
    static final int REQUEST_ALL_PSS_MSG = 39;
    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
    static final int FINISH_BOOTING_MSG = 45;
@@ -2320,12 +2319,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                writeGrantedUriPermissions();
                break;
            }
            case REQUEST_ALL_PSS_MSG: {
                synchronized (ActivityManagerService.this) {
                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
                }
                break;
            }
            case UPDATE_TIME_PREFERENCE_MSG: {
                // The user's time format preference might have changed.
                // For convenience we re-use the Intent extra values.
@@ -2615,11 +2608,17 @@ public class ActivityManagerService extends IActivityManager.Stub
                        procState = proc.pssProcState;
                        statType = proc.pssStatType;
                        lastPssTime = proc.lastPssTime;
                        long now = SystemClock.uptimeMillis();
                        if (proc.thread != null && procState == proc.setProcState
                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
                                        < SystemClock.uptimeMillis()) {
                                        < now) {
                            pid = proc.pid;
                        } else {
                            ProcessList.abortNextPssTime(proc.procStateMemTracker);
                            if (DEBUG_PSS) Slog.d(TAG_PSS, "Skipped pss collection of " + pid +
                                    ": still need " +
                                    (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE-now) +
                                    "ms until safe");
                            proc = null;
                            pid = 0;
                        }
@@ -14477,9 +14476,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                            mTestPssMode, isSleepingLocked(), now);
                }
            }
            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
        }
    }
@@ -19526,6 +19522,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        mProcessesToGc.remove(app);
        mPendingPssProcesses.remove(app);
        ProcessList.abortNextPssTime(app.procStateMemTracker);
        // Dismiss any open dialogs.
        if (app.crashDialog != null && !app.forceCrashReport) {
@@ -23290,9 +23287,9 @@ public class ActivityManagerService extends IActivityManager.Stub
    /**
     * Schedule PSS collection of a process.
     */
    void requestPssLocked(ProcessRecord proc, int procState) {
    boolean requestPssLocked(ProcessRecord proc, int procState) {
        if (mPendingPssProcesses.contains(proc)) {
            return;
            return false;
        }
        if (mPendingPssProcesses.size() == 0) {
            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
@@ -23301,6 +23298,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        proc.pssProcState = procState;
        proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE;
        mPendingPssProcesses.add(proc);
        return true;
    }
    /**
@@ -23317,6 +23315,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of all procs!  memLowered=" + memLowered);
        mLastFullPssTime = now;
        mFullPssPending = true;
        for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
            ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
        }
        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
        mPendingPssProcesses.clear();
        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
@@ -23325,7 +23326,9 @@ public class ActivityManagerService extends IActivityManager.Stub
                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
                continue;
            }
            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
            if (memLowered || (always && now >
                            app.lastStateTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
                    || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
                app.pssProcState = app.setProcState;
                app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
                        : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
@@ -23334,8 +23337,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                mPendingPssProcesses.add(app);
            }
        }
        if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) {
            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
        }
    }
    public void setTestPssMode(boolean enabled) {
        synchronized (this) {
@@ -23692,7 +23697,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                // Experimental code to more aggressively collect pss while
                // running test...  the problem is that this tends to collect
                // the data right when a process is transitioning between process
                // states, which well tend to give noisy data.
                // states, which will tend to give noisy data.
                long start = SystemClock.uptimeMillis();
                long startTime = SystemClock.currentThreadTimeMillis();
                long pss = Debug.getPss(app.pid, mTmpLong, null);
@@ -23715,9 +23720,10 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
                    mTestPssMode)))) {
                requestPssLocked(app, app.setProcState);
                if (requestPssLocked(app, app.setProcState)) {
                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
                            app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
                }
            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
                    "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
        }
+35 −25
Original line number Diff line number Diff line
@@ -501,19 +501,19 @@ public final class ProcessList {
    private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000;

    // The amount of time until PSS when an important process stays in the same state.
    private static final int PSS_SAME_PERSISTENT_INTERVAL = 20*60*1000;
    private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000;

    // The amount of time until PSS when the top process stays in the same state.
    private static final int PSS_SAME_TOP_INTERVAL = 5*60*1000;
    private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000;

    // The amount of time until PSS when an important process stays in the same state.
    private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
    private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000;

    // The amount of time until PSS when a service process stays in the same state.
    private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
    private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000;

    // The amount of time until PSS when a cached process stays in the same state.
    private static final int PSS_SAME_CACHED_INTERVAL = 20*60*1000;
    private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000;

    // The amount of time until PSS when a persistent process first appears.
    private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000;
@@ -622,16 +622,17 @@ public final class ProcessList {

    public static final class ProcStateMemTracker {
        final int[] mHighestMem = new int[PROC_MEM_NUM];
        final float[] mScalingFactor = new float[PROC_MEM_NUM];
        int mTotalHighestMem = PROC_MEM_CACHED;
        float mCurFactor = 1.0f;

        int mPendingMemState;
        int mPendingHighestMemState;
        boolean mPendingSame;
        float mPendingScalingFactor;

        public ProcStateMemTracker() {
            for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) {
                mHighestMem[i] = PROC_MEM_NUM;
                mScalingFactor[i] = 1.0f;
            }
            mPendingMemState = -1;
        }
@@ -639,16 +640,22 @@ public final class ProcessList {
        public void dumpLine(PrintWriter pw) {
            pw.print("best=");
            pw.print(mTotalHighestMem);
            pw.print(" ");
            pw.print(mCurFactor);
            pw.print("x (");
            pw.print(" (");
            boolean needSep = false;
            for (int i = 0; i < PROC_MEM_NUM; i++) {
                if (i != 0) {
                if (mHighestMem[i] < PROC_MEM_NUM) {
                    if (needSep) {
                        pw.print(", ");
                        needSep = false;
                    }
                    pw.print(i);
                    pw.print("=");
                    pw.print(mHighestMem[i]);
                    pw.print(" ");
                    pw.print(mScalingFactor[i]);
                    pw.print("x");
                    needSep = true;
                }
            }
            pw.print(")");
            if (mPendingMemState >= 0) {
@@ -656,8 +663,9 @@ public final class ProcessList {
                pw.print(mPendingMemState);
                pw.print(" highest=");
                pw.print(mPendingHighestMemState);
                pw.print(" same=");
                pw.print(mPendingSame);
                pw.print(" ");
                pw.print(mPendingScalingFactor);
                pw.print("x");
            }
            pw.println();
        }
@@ -674,12 +682,8 @@ public final class ProcessList {
    public static void commitNextPssTime(ProcStateMemTracker tracker) {
        if (tracker.mPendingMemState >= 0) {
            tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState;
            tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor;
            tracker.mTotalHighestMem = tracker.mPendingHighestMemState;
            if (tracker.mPendingSame) {
                tracker.mCurFactor *= 1.5f;
            } else {
                tracker.mCurFactor = 1;
            }
            tracker.mPendingMemState = -1;
        }
    }
@@ -691,6 +695,7 @@ public final class ProcessList {
    public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test,
            boolean sleeping, long now) {
        boolean first;
        float scalingFactor;
        final int memState = sProcStateToProcMem[procState];
        if (tracker != null) {
            final int highestMemState = memState < tracker.mTotalHighestMem
@@ -698,9 +703,15 @@ public final class ProcessList {
            first = highestMemState < tracker.mHighestMem[memState];
            tracker.mPendingMemState = memState;
            tracker.mPendingHighestMemState = highestMemState;
            tracker.mPendingSame = !first;
            if (first) {
                tracker.mPendingScalingFactor = scalingFactor = 1.0f;
            } else {
                scalingFactor = tracker.mScalingFactor[memState];
                tracker.mPendingScalingFactor = scalingFactor * 1.5f;
            }
        } else {
            first = true;
            scalingFactor = 1.0f;
        }
        final long[] table = test
                ? (first
@@ -709,8 +720,7 @@ public final class ProcessList {
                : (first
                ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes)
                : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes));
        long delay = (long)(table[memState] * (tracker != null && !first
                ? tracker.mCurFactor : 1.0f));
        long delay = (long)(table[memState] * scalingFactor);
        if (delay > PSS_MAX_INTERVAL) {
            delay = PSS_MAX_INTERVAL;
        }
+3 −0
Original line number Diff line number Diff line
@@ -237,6 +237,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
            if (commit) {
                mProcessStats.resetSafely();
                updateFile();
                mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
            }
            mLastWriteTime = SystemClock.uptimeMillis();
            totalTime = SystemClock.uptimeMillis() - now;
@@ -784,12 +785,14 @@ public final class ProcessStatsService extends IProcessStats.Stub {
                } else if ("--reset".equals(arg)) {
                    synchronized (mAm) {
                        mProcessStats.resetSafely();
                        mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
                        pw.println("Process stats reset.");
                        quit = true;
                    }
                } else if ("--clear".equals(arg)) {
                    synchronized (mAm) {
                        mProcessStats.resetSafely();
                        mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
                        ArrayList<String> files = getCommittedFiles(0, true, true);
                        if (files != null) {
                            for (int fi=0; fi<files.size(); fi++) {