summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java340
1 files changed, 174 insertions, 166 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7e6d6b1a7849..2c22e53ce27d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17162,6 +17162,179 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@GuardedBy("this")
+ final boolean updateLowMemStateLocked(int numCached, int numEmpty, int numTrimming) {
+ final int N = mProcessList.getLruSizeLocked();
+ final long now = SystemClock.uptimeMillis();
+ // Now determine the memory trimming level of background processes.
+ // Unfortunately we need to start at the back of the list to do this
+ // properly. We only do this if the number of background apps we
+ // are managing to keep around is less than half the maximum we desire;
+ // if we are keeping a good number around, we'll let them use whatever
+ // memory they want.
+ final int numCachedAndEmpty = numCached + numEmpty;
+ int memFactor;
+ if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
+ && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
+ if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
+ } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
+ } else {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
+ }
+ } else {
+ memFactor = ProcessStats.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
+ + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
+ + " numProcs=" + mProcessList.getLruSizeLocked() + " last=" + mLastNumProcesses);
+ if (memFactor > mLastMemoryLevel) {
+ if (!mAllowLowerMemLevel || mProcessList.getLruSizeLocked() >= mLastNumProcesses) {
+ memFactor = mLastMemoryLevel;
+ if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
+ }
+ }
+ if (memFactor != mLastMemoryLevel) {
+ EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
+ StatsLog.write(StatsLog.MEMORY_FACTOR_STATE_CHANGED, memFactor);
+ }
+ mLastMemoryLevel = memFactor;
+ mLastNumProcesses = mProcessList.getLruSizeLocked();
+ boolean allChanged = mProcessStats.setMemFactorLocked(
+ memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
+ final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+ if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
+ if (mLowRamStartTime == 0) {
+ mLowRamStartTime = now;
+ }
+ int step = 0;
+ int fgTrimLevel;
+ switch (memFactor) {
+ case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
+ fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
+ break;
+ case ProcessStats.ADJ_MEM_FACTOR_LOW:
+ fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+ break;
+ default:
+ fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+ break;
+ }
+ int factor = numTrimming/3;
+ int minFactor = 2;
+ if (mAtmInternal.getHomeProcess() != null) minFactor++;
+ if (mAtmInternal.getPreviousProcess() != null) minFactor++;
+ if (factor < minFactor) factor = minFactor;
+ int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
+ for (int i=N-1; i>=0; i--) {
+ ProcessRecord app = mProcessList.mLruProcesses.get(i);
+ if (allChanged || app.procStateChanged) {
+ setProcessTrackerStateLocked(app, trackerMemFactor, now);
+ app.procStateChanged = false;
+ }
+ if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
+ && !app.killedByAm) {
+ if (app.trimMemoryLevel < curLevel && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of " + app.processName + " to " + curLevel);
+ app.thread.scheduleTrimMemory(curLevel);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = curLevel;
+ step++;
+ if (step >= factor) {
+ step = 0;
+ switch (curLevel) {
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+ curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+ curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+ break;
+ }
+ }
+ } else if (app.getCurProcState() == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+ && !app.killedByAm) {
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
+ && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of heavy-weight " + app.processName
+ + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+ } else {
+ if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+ || app.systemNoUi) && app.hasPendingUiClean()) {
+ // If this application is now in the background and it
+ // had done UI, then give it the special trim level to
+ // have it free UI resources.
+ final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
+ if (app.trimMemoryLevel < level && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of bg-ui " + app.processName
+ + " to " + level);
+ app.thread.scheduleTrimMemory(level);
+ } catch (RemoteException e) {
+ }
+ }
+ app.setPendingUiClean(false);
+ }
+ if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of fg " + app.processName
+ + " to " + fgTrimLevel);
+ app.thread.scheduleTrimMemory(fgTrimLevel);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = fgTrimLevel;
+ }
+ }
+ } else {
+ if (mLowRamStartTime != 0) {
+ mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
+ mLowRamStartTime = 0;
+ }
+ for (int i=N-1; i>=0; i--) {
+ ProcessRecord app = mProcessList.mLruProcesses.get(i);
+ if (allChanged || app.procStateChanged) {
+ setProcessTrackerStateLocked(app, trackerMemFactor, now);
+ app.procStateChanged = false;
+ }
+ if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+ || app.systemNoUi) && app.hasPendingUiClean()) {
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
+ && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of ui hidden " + app.processName
+ + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ } catch (RemoteException e) {
+ }
+ }
+ app.setPendingUiClean(false);
+ }
+ app.trimMemoryLevel = 0;
+ }
+ }
+ return allChanged;
+ }
+
+ @GuardedBy("this")
final void updateOomAdjLocked() {
mOomAdjProfiler.oomAdjStarted();
final ProcessRecord TOP_APP = getTopAppLocked();
@@ -17393,172 +17566,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mNumServiceProcs = mNewNumServiceProcs;
- // Now determine the memory trimming level of background processes.
- // Unfortunately we need to start at the back of the list to do this
- // properly. We only do this if the number of background apps we
- // are managing to keep around is less than half the maximum we desire;
- // if we are keeping a good number around, we'll let them use whatever
- // memory they want.
- final int numCachedAndEmpty = numCached + numEmpty;
- int memFactor;
- if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
- && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
- if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
- } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
- } else {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
- }
- } else {
- memFactor = ProcessStats.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
- + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
- + " numProcs=" + mProcessList.getLruSizeLocked() + " last=" + mLastNumProcesses);
- if (memFactor > mLastMemoryLevel) {
- if (!mAllowLowerMemLevel || mProcessList.getLruSizeLocked() >= mLastNumProcesses) {
- memFactor = mLastMemoryLevel;
- if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
- }
- }
- if (memFactor != mLastMemoryLevel) {
- EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
- StatsLog.write(StatsLog.MEMORY_FACTOR_STATE_CHANGED, memFactor);
- }
- mLastMemoryLevel = memFactor;
- mLastNumProcesses = mProcessList.getLruSizeLocked();
- boolean allChanged = mProcessStats.setMemFactorLocked(
- memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
- final int trackerMemFactor = mProcessStats.getMemFactorLocked();
- if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
- if (mLowRamStartTime == 0) {
- mLowRamStartTime = now;
- }
- int step = 0;
- int fgTrimLevel;
- switch (memFactor) {
- case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
- fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
- break;
- case ProcessStats.ADJ_MEM_FACTOR_LOW:
- fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
- break;
- default:
- fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
- break;
- }
- int factor = numTrimming/3;
- int minFactor = 2;
- if (mAtmInternal.getHomeProcess() != null) minFactor++;
- if (mAtmInternal.getPreviousProcess() != null) minFactor++;
- if (factor < minFactor) factor = minFactor;
- int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
- for (int i=N-1; i>=0; i--) {
- ProcessRecord app = mProcessList.mLruProcesses.get(i);
- if (allChanged || app.procStateChanged) {
- setProcessTrackerStateLocked(app, trackerMemFactor, now);
- app.procStateChanged = false;
- }
- if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
- && !app.killedByAm) {
- if (app.trimMemoryLevel < curLevel && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of " + app.processName + " to " + curLevel);
- app.thread.scheduleTrimMemory(curLevel);
- } catch (RemoteException e) {
- }
- }
- app.trimMemoryLevel = curLevel;
- step++;
- if (step >= factor) {
- step = 0;
- switch (curLevel) {
- case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
- curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
- break;
- case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
- curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
- break;
- }
- }
- } else if (app.getCurProcState() == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
- && !app.killedByAm) {
- if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
- && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of heavy-weight " + app.processName
- + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
- app.thread.scheduleTrimMemory(
- ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
- } catch (RemoteException e) {
- }
- }
- app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
- } else {
- if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
- || app.systemNoUi) && app.hasPendingUiClean()) {
- // If this application is now in the background and it
- // had done UI, then give it the special trim level to
- // have it free UI resources.
- final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
- if (app.trimMemoryLevel < level && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of bg-ui " + app.processName
- + " to " + level);
- app.thread.scheduleTrimMemory(level);
- } catch (RemoteException e) {
- }
- }
- app.setPendingUiClean(false);
- }
- if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of fg " + app.processName
- + " to " + fgTrimLevel);
- app.thread.scheduleTrimMemory(fgTrimLevel);
- } catch (RemoteException e) {
- }
- }
- app.trimMemoryLevel = fgTrimLevel;
- }
- }
- } else {
- if (mLowRamStartTime != 0) {
- mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
- mLowRamStartTime = 0;
- }
- for (int i=N-1; i>=0; i--) {
- ProcessRecord app = mProcessList.mLruProcesses.get(i);
- if (allChanged || app.procStateChanged) {
- setProcessTrackerStateLocked(app, trackerMemFactor, now);
- app.procStateChanged = false;
- }
- if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
- || app.systemNoUi) && app.hasPendingUiClean()) {
- if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
- && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of ui hidden " + app.processName
- + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
- app.thread.scheduleTrimMemory(
- ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
- } catch (RemoteException e) {
- }
- }
- app.setPendingUiClean(false);
- }
- app.trimMemoryLevel = 0;
- }
- }
+ boolean allChanged = updateLowMemStateLocked(numCached, numEmpty, numTrimming);
if (mAlwaysFinishActivities) {
// Need to do this on its own message because the stack may not