Loading services/java/com/android/server/am/ActivityManagerService.java +59 −60 Original line number Diff line number Diff line Loading @@ -229,6 +229,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_URI_PERMISSION = localLOGV || false; static final boolean DEBUG_USER_LEAVING = localLOGV || false; static final boolean DEBUG_VISBILITY = localLOGV || false; static final boolean DEBUG_PSS = localLOGV || false; static final boolean VALIDATE_TOKENS = true; static final boolean SHOW_ACTIVITY_START_TIME = true; Loading Loading @@ -269,24 +270,13 @@ public final class ActivityManagerService extends ActivityManagerNative // The minimum amount of time between successive GC requests for a process. static final int GC_MIN_INTERVAL = 60*1000; // The minimum amount of time between successive PSS requests for a process. static final int PSS_MIN_INTERVAL = 2*60*1000; // The amount of time we will sample PSS of the current top process while the // screen is on. static final int PSS_TOP_INTERVAL = 2*60*1000; // The amount of time we will sample PSS of any processes that more at least as // important as perceptible while the screen is on. static final int PSS_PERCEPTIBLE_INTERVAL = 10*60*1000; // The maximum amount of time for a process to be around until we will take // a PSS snapshot on its next oom change. static final int PSS_MAX_INTERVAL = 30*60*1000; // The minimum amount of time between successive PSS requests for a process. static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; // The minimum amount of time between successive PSS requests for a process // when the request is due to the memory state being lowered. static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; // The rate at which we check for apps using excessive power -- 15 mins. static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; Loading Loading @@ -1497,27 +1487,26 @@ public final class ActivityManagerService extends ActivityManagerNative public void handleMessage(Message msg) { switch (msg.what) { case COLLECT_PSS_BG_MSG: { int i=0; int i=0, num=0; long start = SystemClock.uptimeMillis(); long[] tmp = new long[1]; do { ProcessRecord proc; int oomAdj; int procState; int pid; synchronized (ActivityManagerService.this) { if (i >= mPendingPssProcesses.size()) { Slog.i(TAG, "Collected PSS of " + i + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); if (DEBUG_PSS) Slog.i(TAG, "Collected PSS of " + num + " of " + i + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); mPendingPssProcesses.clear(); return; } proc = mPendingPssProcesses.get(i); if (proc.thread != null) { oomAdj = proc.setAdj; procState = proc.pssProcState; if (proc.thread != null && procState == proc.setProcState) { pid = proc.pid; } else { proc = null; oomAdj = 0; pid = 0; } i++; Loading @@ -1525,7 +1514,10 @@ public final class ActivityManagerService extends ActivityManagerNative if (proc != null) { long pss = Debug.getPss(pid, tmp); synchronized (ActivityManagerService.this) { if (proc.thread != null && proc.setAdj == oomAdj && proc.pid == pid) { if (proc.thread != null && proc.setProcState == procState && proc.pid == pid) { num++; proc.lastPssTime = SystemClock.uptimeMillis(); proc.baseProcessTracker.addPss(pss, tmp[0], true); } } Loading Loading @@ -4770,7 +4762,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean sticky, int sendingUser) { synchronized (ActivityManagerService.this) { requestPssAllProcsLocked(SystemClock.uptimeMillis(), true); true, false); } } }, Loading Loading @@ -14173,35 +14165,41 @@ public final class ActivityManagerService extends ActivityManagerNative /** * Schedule PSS collection of a process. */ void requestPssLocked(ProcessRecord proc, long now, boolean always) { if (!always && now < (proc.lastPssTime+PSS_MIN_INTERVAL)) { return; } void requestPssLocked(ProcessRecord proc, int procState) { if (mPendingPssProcesses.contains(proc)) { return; } proc.lastPssTime = now; if (mPendingPssProcesses.size() == 0) { mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); } if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); proc.pssProcState = procState; mPendingPssProcesses.add(proc); } /** * Schedule PSS collection of all processes. */ void requestPssAllProcsLocked(long now, boolean always) { if (!always && now < (mLastFullPssTime+FULL_PSS_MIN_INTERVAL)) { void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { if (!always) { if (now < (mLastFullPssTime + (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { return; } } if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); mLastFullPssTime = now; mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); mPendingPssProcesses.clear(); for (int i=mLruProcesses.size()-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); app.lastPssTime = now; if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { app.pssProcState = app.setProcState; app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, mSleeping, now); mPendingPssProcesses.add(app); } } mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); } Loading Loading @@ -14459,32 +14457,11 @@ public final class ActivityManagerService extends ActivityManagerNative app.setRawAdj = app.curRawAdj; } if (!mSleeping) { if (app == TOP_APP && now > (app.lastPssTime+PSS_TOP_INTERVAL)) { // For the current top application we will very aggressively collect // PSS data to have a good measure of memory use while in the foreground. requestPssLocked(app, now, true); } else if (app.curAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && now > (app.lastPssTime+PSS_TOP_INTERVAL)) { // For any unkillable processes, we will more regularly collect their PSS // since they have a significant impact on the memory state of the device. requestPssLocked(app, now, true); } } if (app.curAdj != app.setAdj) { if (Process.setOomAdj(app.pid, app.curAdj)) { if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( TAG, "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": " + app.adjType); if (app.setAdj == ProcessList.SERVICE_ADJ && app.curAdj == ProcessList.SERVICE_B_ADJ) { // If a service is dropping to the B list, it has been running for // a while, take a PSS snapshot. requestPssLocked(app, now, false); } else if (now > (app.lastPssTime+PSS_MAX_INTERVAL)) { requestPssLocked(app, now, true); } app.setAdj = app.curAdj; } else { success = false; Loading Loading @@ -14542,19 +14519,39 @@ public final class ActivityManagerService extends ActivityManagerNative } } } if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { if (DEBUG_PSS) Slog.d(TAG, "Process state change from " + app.setProcState + " to " + app.curProcState + ": " + app); app.lastStateTime = now; app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, mSleeping, now); } else { if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { requestPssLocked(app, app.setProcState); app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, mSleeping, now); } } if (app.setProcState != app.curProcState) { if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, "Proc state change of " + app.processName + " to " + app.curProcState); app.setProcState = app.curProcState; app.procStateChanged = true; if (!doingAll) { app.setProcessTrackerState(mProcessTracker.getMemFactorLocked(), now); setProcessTrackerState(app, mProcessTracker.getMemFactorLocked(), now); } else { app.procStateChanged = true; } } return success; } private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); } private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { if (app.thread == null) { Loading Loading @@ -14835,7 +14832,8 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=N-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); if (allChanged || app.procStateChanged) { app.setProcessTrackerState(trackerMemFactor, now); setProcessTrackerState(app, trackerMemFactor, now); app.procStateChanged = false; } if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME && !app.killedBackground) { Loading Loading @@ -14924,7 +14922,8 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=N-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); if (allChanged || app.procStateChanged) { app.setProcessTrackerState(ProcessTracker.ADJ_MEM_FACTOR_NORMAL, now); setProcessTrackerState(app, trackerMemFactor, now); app.procStateChanged = false; } if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND || app.systemNoUi) && app.pendingUiClean) { Loading Loading @@ -14952,7 +14951,7 @@ public final class ActivityManagerService extends ActivityManagerNative } if (allChanged) { requestPssAllProcsLocked(now, false); requestPssAllProcsLocked(now, false, mProcessTracker.isMemFactorLowered()); } if (mProcessTracker.shouldWriteNowLocked(now)) { services/java/com/android/server/am/ActivityStackSupervisor.java +0 −1 Original line number Diff line number Diff line Loading @@ -1783,7 +1783,6 @@ public final class ActivityStackSupervisor { if (allResumedActivitiesIdle()) { if (r != null) { mService.scheduleAppGcsLocked(); mService.requestPssLocked(r.app, SystemClock.uptimeMillis(), false); } if (mLaunchingActivity.isHeld()) { Loading services/java/com/android/server/am/ProcessList.java +100 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,106 @@ final class ProcessList { return (totalProcessLimit*2)/3; } // The minimum amount of time after a state change it is safe ro collect PSS. public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000; // The maximum amount of time we want to go between PSS collections. public static final int PSS_MAX_INTERVAL = 30*60*1000; // The minimum amount of time between successive PSS requests for *all* processes. public static final int PSS_ALL_INTERVAL = 10*60*1000; // The minimum amount of time between successive PSS requests for a process. private static final int PSS_SHORT_INTERVAL = 2*60*1000; // The amount of time until PSS when a process first becomes top. private static final int PSS_FIRST_TOP_INTERVAL = 15*1000; // The amount of time until PSS when a process first becomes cached. private static final int PSS_FIRST_CACHED_INTERVAL = 5*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; // 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; // The amount of time until PSS when a cached process stays in the same state. private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000; public static final int PROC_MEM_PERSISTENT = 0; public static final int PROC_MEM_TOP = 1; public static final int PROC_MEM_IMPORTANT = 2; public static final int PROC_MEM_SERVICE = 3; public static final int PROC_MEM_CACHED = 4; private static final int[] sProcStateToProcMem = new int[] { PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; private static final long[] sFirstAwakePssTimes = new long[] { PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI PSS_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; private static final long[] sSameAwakePssTimes = new long[] { PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; public static boolean procStatesDifferForMem(int procState1, int procState2) { return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; } public static long computeNextPssTime(int procState, boolean first, boolean sleeping, long now) { final long[] table = sleeping ? (first ? sFirstAwakePssTimes : sSameAwakePssTimes) : (first ? sFirstAwakePssTimes : sSameAwakePssTimes); return now + table[procState]; } long getMemLevel(int adjustment) { for (int i=0; i<mOomAdj.length; i++) { if (adjustment <= mOomAdj[i]) { Loading services/java/com/android/server/am/ProcessRecord.java +15 −8 Original line number Diff line number Diff line Loading @@ -62,7 +62,9 @@ final class ProcessRecord { boolean starting; // True if the process is being started long lastActivityTime; // For managing the LRU list long lruWeight; // Weight for ordering in LRU list long lastPssTime; // Last time we requested PSS data long lastPssTime; // Last time we retrieved PSS data long nextPssTime; // Next time we want to request PSS data long lastStateTime; // Last time setProcState changed int maxAdj; // Maximum OOM adjustment for this process int curRawAdj; // Current OOM unlimited adjustment for this process int setRawAdj; // Last set OOM unlimited adjustment for this process Loading @@ -75,6 +77,7 @@ final class ProcessRecord { int curProcState = -1; // Currently computed process state: ActivityManager.PROCESS_STATE_* int repProcState = -1; // Last reported process state int setProcState = -1; // Last set process state in process tracker int pssProcState = -1; // The proc state we are currently requesting pss for boolean serviceb; // Process currently is on the service B list boolean keeping; // Actively running code so don't kill due to that? boolean setIsForeground; // Running foreground UI when last set? Loading Loading @@ -223,10 +226,18 @@ final class ProcessRecord { pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel); pw.print(prefix); pw.print("curProcState="); pw.print(curProcState); pw.print(" repProcState="); pw.print(repProcState); pw.print(" setProcState="); pw.println(setProcState); pw.print(" pssProcState="); pw.print(pssProcState); pw.print(" setProcState="); pw.print(setProcState); pw.print(" lastStateTime="); TimeUtils.formatDuration(lastStateTime, now, pw); pw.println(); pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); pw.print(" lruSeq="); pw.print(lruSeq); pw.print(" lastPssTime="); pw.println(lastPssTime); pw.print(" lastPssTime="); TimeUtils.formatDuration(lastPssTime, now, pw); pw.print(" nextPssTime="); TimeUtils.formatDuration(nextPssTime, now, pw); pw.println(); if (hasShownUi || pendingUiClean || hasAboveClient) { pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi); pw.print(" pendingUiClean="); pw.print(pendingUiClean); Loading Loading @@ -354,7 +365,7 @@ final class ProcessRecord { curAdj = setAdj = -100; persistent = false; removed = false; lastPssTime = SystemClock.uptimeMillis(); lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis(); } public void setPid(int _pid) { Loading Loading @@ -499,10 +510,6 @@ final class ProcessRecord { } } public void setProcessTrackerState(int memFactor, long now) { baseProcessTracker.setState(repProcState, memFactor, now, pkgList); } /* * Delete all packages from list except the package indicated in info */ Loading services/java/com/android/server/am/ProcessTracker.java +8 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,8 @@ public final class ProcessTracker { State mState; boolean mCommitPending; boolean mShuttingDown; int mLastMemOnlyState = -1; boolean mMemFactorLowered; final ReentrantLock mWriteLock = new ReentrantLock(); Loading Loading @@ -1822,7 +1824,13 @@ public final class ProcessTracker { return ss; } public boolean isMemFactorLowered() { return mMemFactorLowered; } public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) { mMemFactorLowered = memFactor < mLastMemOnlyState; mLastMemOnlyState = memFactor; if (screenOn) { memFactor += ADJ_SCREEN_ON; } Loading Loading
services/java/com/android/server/am/ActivityManagerService.java +59 −60 Original line number Diff line number Diff line Loading @@ -229,6 +229,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_URI_PERMISSION = localLOGV || false; static final boolean DEBUG_USER_LEAVING = localLOGV || false; static final boolean DEBUG_VISBILITY = localLOGV || false; static final boolean DEBUG_PSS = localLOGV || false; static final boolean VALIDATE_TOKENS = true; static final boolean SHOW_ACTIVITY_START_TIME = true; Loading Loading @@ -269,24 +270,13 @@ public final class ActivityManagerService extends ActivityManagerNative // The minimum amount of time between successive GC requests for a process. static final int GC_MIN_INTERVAL = 60*1000; // The minimum amount of time between successive PSS requests for a process. static final int PSS_MIN_INTERVAL = 2*60*1000; // The amount of time we will sample PSS of the current top process while the // screen is on. static final int PSS_TOP_INTERVAL = 2*60*1000; // The amount of time we will sample PSS of any processes that more at least as // important as perceptible while the screen is on. static final int PSS_PERCEPTIBLE_INTERVAL = 10*60*1000; // The maximum amount of time for a process to be around until we will take // a PSS snapshot on its next oom change. static final int PSS_MAX_INTERVAL = 30*60*1000; // The minimum amount of time between successive PSS requests for a process. static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; // The minimum amount of time between successive PSS requests for a process // when the request is due to the memory state being lowered. static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; // The rate at which we check for apps using excessive power -- 15 mins. static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; Loading Loading @@ -1497,27 +1487,26 @@ public final class ActivityManagerService extends ActivityManagerNative public void handleMessage(Message msg) { switch (msg.what) { case COLLECT_PSS_BG_MSG: { int i=0; int i=0, num=0; long start = SystemClock.uptimeMillis(); long[] tmp = new long[1]; do { ProcessRecord proc; int oomAdj; int procState; int pid; synchronized (ActivityManagerService.this) { if (i >= mPendingPssProcesses.size()) { Slog.i(TAG, "Collected PSS of " + i + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); if (DEBUG_PSS) Slog.i(TAG, "Collected PSS of " + num + " of " + i + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); mPendingPssProcesses.clear(); return; } proc = mPendingPssProcesses.get(i); if (proc.thread != null) { oomAdj = proc.setAdj; procState = proc.pssProcState; if (proc.thread != null && procState == proc.setProcState) { pid = proc.pid; } else { proc = null; oomAdj = 0; pid = 0; } i++; Loading @@ -1525,7 +1514,10 @@ public final class ActivityManagerService extends ActivityManagerNative if (proc != null) { long pss = Debug.getPss(pid, tmp); synchronized (ActivityManagerService.this) { if (proc.thread != null && proc.setAdj == oomAdj && proc.pid == pid) { if (proc.thread != null && proc.setProcState == procState && proc.pid == pid) { num++; proc.lastPssTime = SystemClock.uptimeMillis(); proc.baseProcessTracker.addPss(pss, tmp[0], true); } } Loading Loading @@ -4770,7 +4762,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean sticky, int sendingUser) { synchronized (ActivityManagerService.this) { requestPssAllProcsLocked(SystemClock.uptimeMillis(), true); true, false); } } }, Loading Loading @@ -14173,35 +14165,41 @@ public final class ActivityManagerService extends ActivityManagerNative /** * Schedule PSS collection of a process. */ void requestPssLocked(ProcessRecord proc, long now, boolean always) { if (!always && now < (proc.lastPssTime+PSS_MIN_INTERVAL)) { return; } void requestPssLocked(ProcessRecord proc, int procState) { if (mPendingPssProcesses.contains(proc)) { return; } proc.lastPssTime = now; if (mPendingPssProcesses.size() == 0) { mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); } if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); proc.pssProcState = procState; mPendingPssProcesses.add(proc); } /** * Schedule PSS collection of all processes. */ void requestPssAllProcsLocked(long now, boolean always) { if (!always && now < (mLastFullPssTime+FULL_PSS_MIN_INTERVAL)) { void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { if (!always) { if (now < (mLastFullPssTime + (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { return; } } if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); mLastFullPssTime = now; mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); mPendingPssProcesses.clear(); for (int i=mLruProcesses.size()-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); app.lastPssTime = now; if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { app.pssProcState = app.setProcState; app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, mSleeping, now); mPendingPssProcesses.add(app); } } mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); } Loading Loading @@ -14459,32 +14457,11 @@ public final class ActivityManagerService extends ActivityManagerNative app.setRawAdj = app.curRawAdj; } if (!mSleeping) { if (app == TOP_APP && now > (app.lastPssTime+PSS_TOP_INTERVAL)) { // For the current top application we will very aggressively collect // PSS data to have a good measure of memory use while in the foreground. requestPssLocked(app, now, true); } else if (app.curAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && now > (app.lastPssTime+PSS_TOP_INTERVAL)) { // For any unkillable processes, we will more regularly collect their PSS // since they have a significant impact on the memory state of the device. requestPssLocked(app, now, true); } } if (app.curAdj != app.setAdj) { if (Process.setOomAdj(app.pid, app.curAdj)) { if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( TAG, "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": " + app.adjType); if (app.setAdj == ProcessList.SERVICE_ADJ && app.curAdj == ProcessList.SERVICE_B_ADJ) { // If a service is dropping to the B list, it has been running for // a while, take a PSS snapshot. requestPssLocked(app, now, false); } else if (now > (app.lastPssTime+PSS_MAX_INTERVAL)) { requestPssLocked(app, now, true); } app.setAdj = app.curAdj; } else { success = false; Loading Loading @@ -14542,19 +14519,39 @@ public final class ActivityManagerService extends ActivityManagerNative } } } if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { if (DEBUG_PSS) Slog.d(TAG, "Process state change from " + app.setProcState + " to " + app.curProcState + ": " + app); app.lastStateTime = now; app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, mSleeping, now); } else { if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { requestPssLocked(app, app.setProcState); app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, mSleeping, now); } } if (app.setProcState != app.curProcState) { if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, "Proc state change of " + app.processName + " to " + app.curProcState); app.setProcState = app.curProcState; app.procStateChanged = true; if (!doingAll) { app.setProcessTrackerState(mProcessTracker.getMemFactorLocked(), now); setProcessTrackerState(app, mProcessTracker.getMemFactorLocked(), now); } else { app.procStateChanged = true; } } return success; } private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); } private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { if (app.thread == null) { Loading Loading @@ -14835,7 +14832,8 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=N-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); if (allChanged || app.procStateChanged) { app.setProcessTrackerState(trackerMemFactor, now); setProcessTrackerState(app, trackerMemFactor, now); app.procStateChanged = false; } if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME && !app.killedBackground) { Loading Loading @@ -14924,7 +14922,8 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=N-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); if (allChanged || app.procStateChanged) { app.setProcessTrackerState(ProcessTracker.ADJ_MEM_FACTOR_NORMAL, now); setProcessTrackerState(app, trackerMemFactor, now); app.procStateChanged = false; } if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND || app.systemNoUi) && app.pendingUiClean) { Loading Loading @@ -14952,7 +14951,7 @@ public final class ActivityManagerService extends ActivityManagerNative } if (allChanged) { requestPssAllProcsLocked(now, false); requestPssAllProcsLocked(now, false, mProcessTracker.isMemFactorLowered()); } if (mProcessTracker.shouldWriteNowLocked(now)) {
services/java/com/android/server/am/ActivityStackSupervisor.java +0 −1 Original line number Diff line number Diff line Loading @@ -1783,7 +1783,6 @@ public final class ActivityStackSupervisor { if (allResumedActivitiesIdle()) { if (r != null) { mService.scheduleAppGcsLocked(); mService.requestPssLocked(r.app, SystemClock.uptimeMillis(), false); } if (mLaunchingActivity.isHeld()) { Loading
services/java/com/android/server/am/ProcessList.java +100 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,106 @@ final class ProcessList { return (totalProcessLimit*2)/3; } // The minimum amount of time after a state change it is safe ro collect PSS. public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000; // The maximum amount of time we want to go between PSS collections. public static final int PSS_MAX_INTERVAL = 30*60*1000; // The minimum amount of time between successive PSS requests for *all* processes. public static final int PSS_ALL_INTERVAL = 10*60*1000; // The minimum amount of time between successive PSS requests for a process. private static final int PSS_SHORT_INTERVAL = 2*60*1000; // The amount of time until PSS when a process first becomes top. private static final int PSS_FIRST_TOP_INTERVAL = 15*1000; // The amount of time until PSS when a process first becomes cached. private static final int PSS_FIRST_CACHED_INTERVAL = 5*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; // 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; // The amount of time until PSS when a cached process stays in the same state. private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000; public static final int PROC_MEM_PERSISTENT = 0; public static final int PROC_MEM_TOP = 1; public static final int PROC_MEM_IMPORTANT = 2; public static final int PROC_MEM_SERVICE = 3; public static final int PROC_MEM_CACHED = 4; private static final int[] sProcStateToProcMem = new int[] { PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; private static final long[] sFirstAwakePssTimes = new long[] { PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI PSS_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; private static final long[] sSameAwakePssTimes = new long[] { PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY }; public static boolean procStatesDifferForMem(int procState1, int procState2) { return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; } public static long computeNextPssTime(int procState, boolean first, boolean sleeping, long now) { final long[] table = sleeping ? (first ? sFirstAwakePssTimes : sSameAwakePssTimes) : (first ? sFirstAwakePssTimes : sSameAwakePssTimes); return now + table[procState]; } long getMemLevel(int adjustment) { for (int i=0; i<mOomAdj.length; i++) { if (adjustment <= mOomAdj[i]) { Loading
services/java/com/android/server/am/ProcessRecord.java +15 −8 Original line number Diff line number Diff line Loading @@ -62,7 +62,9 @@ final class ProcessRecord { boolean starting; // True if the process is being started long lastActivityTime; // For managing the LRU list long lruWeight; // Weight for ordering in LRU list long lastPssTime; // Last time we requested PSS data long lastPssTime; // Last time we retrieved PSS data long nextPssTime; // Next time we want to request PSS data long lastStateTime; // Last time setProcState changed int maxAdj; // Maximum OOM adjustment for this process int curRawAdj; // Current OOM unlimited adjustment for this process int setRawAdj; // Last set OOM unlimited adjustment for this process Loading @@ -75,6 +77,7 @@ final class ProcessRecord { int curProcState = -1; // Currently computed process state: ActivityManager.PROCESS_STATE_* int repProcState = -1; // Last reported process state int setProcState = -1; // Last set process state in process tracker int pssProcState = -1; // The proc state we are currently requesting pss for boolean serviceb; // Process currently is on the service B list boolean keeping; // Actively running code so don't kill due to that? boolean setIsForeground; // Running foreground UI when last set? Loading Loading @@ -223,10 +226,18 @@ final class ProcessRecord { pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel); pw.print(prefix); pw.print("curProcState="); pw.print(curProcState); pw.print(" repProcState="); pw.print(repProcState); pw.print(" setProcState="); pw.println(setProcState); pw.print(" pssProcState="); pw.print(pssProcState); pw.print(" setProcState="); pw.print(setProcState); pw.print(" lastStateTime="); TimeUtils.formatDuration(lastStateTime, now, pw); pw.println(); pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); pw.print(" lruSeq="); pw.print(lruSeq); pw.print(" lastPssTime="); pw.println(lastPssTime); pw.print(" lastPssTime="); TimeUtils.formatDuration(lastPssTime, now, pw); pw.print(" nextPssTime="); TimeUtils.formatDuration(nextPssTime, now, pw); pw.println(); if (hasShownUi || pendingUiClean || hasAboveClient) { pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi); pw.print(" pendingUiClean="); pw.print(pendingUiClean); Loading Loading @@ -354,7 +365,7 @@ final class ProcessRecord { curAdj = setAdj = -100; persistent = false; removed = false; lastPssTime = SystemClock.uptimeMillis(); lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis(); } public void setPid(int _pid) { Loading Loading @@ -499,10 +510,6 @@ final class ProcessRecord { } } public void setProcessTrackerState(int memFactor, long now) { baseProcessTracker.setState(repProcState, memFactor, now, pkgList); } /* * Delete all packages from list except the package indicated in info */ Loading
services/java/com/android/server/am/ProcessTracker.java +8 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,8 @@ public final class ProcessTracker { State mState; boolean mCommitPending; boolean mShuttingDown; int mLastMemOnlyState = -1; boolean mMemFactorLowered; final ReentrantLock mWriteLock = new ReentrantLock(); Loading Loading @@ -1822,7 +1824,13 @@ public final class ProcessTracker { return ss; } public boolean isMemFactorLowered() { return mMemFactorLowered; } public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) { mMemFactorLowered = memFactor < mLastMemOnlyState; mLastMemOnlyState = memFactor; if (screenOn) { memFactor += ADJ_SCREEN_ON; } Loading