diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a6c4fc952839d..2d443a3251827 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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; } @@ -14480,9 +14479,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); } } @@ -19529,6 +19525,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) { @@ -23293,9 +23290,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); @@ -23304,6 +23301,7 @@ public class ActivityManagerService extends IActivityManager.Stub proc.pssProcState = procState; proc.pssStatType = ProcessStats.ADD_PSS_INTERNAL_SINGLE; mPendingPssProcesses.add(proc); + return true; } /** @@ -23320,6 +23318,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--) { @@ -23328,7 +23329,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; @@ -23337,7 +23340,9 @@ public class ActivityManagerService extends IActivityManager.Stub mPendingPssProcesses.add(app); } } - mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); + if (!mBgHandler.hasMessages(COLLECT_PSS_BG_MSG)) { + mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); + } } public void setTestPssMode(boolean enabled) { @@ -23695,7 +23700,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); @@ -23718,9 +23723,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); - app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, - app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now); + 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)); } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 08ee23723df44..bf7aef9ecc65a 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -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) { - pw.print(", "); + 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(i); - pw.print("="); - pw.print(mHighestMem[i]); } 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; } diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java index 8bf320e0c3879..edf565abd7df3 100644 --- a/services/core/java/com/android/server/am/ProcessStatsService.java +++ b/services/core/java/com/android/server/am/ProcessStatsService.java @@ -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 files = getCommittedFiles(0, true, true); if (files != null) { for (int fi=0; fi