From 8633e68ebdf215f721834f7aa16c2f3cef1bae86 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 22 Apr 2010 16:03:41 -0700 Subject: [PATCH] Fix issue #2619247: Music sometimes stops playing when navigation talks When a service transitions from foreground to background, we now push it to the top of the LRU list. Also fix the activity manager to take care of killing processes if we go beyond a reasonable number of background process to keep around. Change-Id: Ic9f44c02af7a111ee6f1d06142386b301948bafe --- .../server/am/ActivityManagerService.java | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 7e095b588a933..436bd17d0f805 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -315,6 +315,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // without empty apps being able to push them out of memory. static final int MIN_HIDDEN_APPS = 2; + // The maximum number of hidden processes we will keep around before + // killing them; this is just a control to not let us go too crazy with + // keeping around processes on devices with large amounts of RAM. + static final int MAX_HIDDEN_APPS = 15; + // We put empty content processes after any hidden processes that have // been idle for less than 30 seconds. static final long CONTENT_APP_IDLE_OFFSET = 30*1000; @@ -8488,8 +8493,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } int adj = proc.setAdj; if (adj >= worstType) { - Slog.w(TAG, "Killing " + reason + " : " + proc + " (adj " - + adj + ")"); + Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); killed = true; @@ -8904,9 +8908,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } if (app.pid > 0 && app.pid != MY_PID) { handleAppCrashLocked(app); - Slog.i(ActivityManagerService.TAG, "Killing process " - + app.processName - + " (pid=" + app.pid + ") at user's request"); + Slog.i(ActivityManagerService.TAG, "Killing " + + app.processName + " (pid=" + app.pid + "): user's request"); + EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, + app.processName, app.setAdj, "user's request after error"); Process.killProcess(app.pid); } } @@ -10434,10 +10439,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (!capp.persistent && capp.thread != null && capp.pid != 0 && capp.pid != MY_PID) { - Slog.i(TAG, "Killing app " + capp.processName - + " (pid " + capp.pid - + ") because provider " + cpr.info.name - + " is in dying process " + proc.processName); + Slog.i(TAG, "Kill " + capp.processName + + " (pid " + capp.pid + "): provider " + cpr.info.name + + " in dying process " + proc.processName); + EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, + capp.processName, capp.setAdj, "dying provider " + proc.processName); Process.killProcess(capp.pid); } } @@ -11522,6 +11528,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.isForeground) { r.isForeground = false; if (r.app != null) { + updateLruProcessLocked(r.app, false, true); updateServiceForegroundLocked(r.app, true); } } @@ -14244,6 +14251,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int factor = (mLruProcesses.size()-4)/numSlots; if (factor < 1) factor = 1; int step = 0; + int numHidden = 0; // First try updating the OOM adjustment for each of the // application processes based on their current state. @@ -14262,6 +14270,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen curHiddenAdj++; } } + if (app.curAdj >= HIDDEN_APP_MIN_ADJ) { + numHidden++; + if (numHidden > MAX_HIDDEN_APPS) { + Slog.i(TAG, "Kill " + app.processName + + " (pid " + app.pid + "): hidden #" + numHidden + + " beyond limit " + MAX_HIDDEN_APPS); + EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, + app.processName, app.setAdj, "too many background"); + Process.killProcess(app.pid); + } + } } else { didOomAdj = false; }