summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/am/ActivityManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/am/ActivityManagerService.java')
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java240
1 files changed, 165 insertions, 75 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b266bd4..370d427 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1369,7 +1369,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (mSelf.mPidsSelfLocked) {
mSelf.mPidsSelfLocked.put(app.pid, app);
}
- mSelf.updateLruProcessLocked(app, true, true);
+ mSelf.updateLruProcessLocked(app, true);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
@@ -1805,8 +1805,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- private final void updateLruProcessInternalLocked(ProcessRecord app,
- boolean updateActivityTime, int bestPos) {
+ private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
// put it on the LRU to keep track of when it should be exited.
int lrui = mLruProcesses.indexOf(app);
if (lrui >= 0) mLruProcesses.remove(lrui);
@@ -1817,9 +1816,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.lruSeq = mLruSeq;
// compute the new weight for this process.
- if (updateActivityTime) {
- app.lastActivityTime = SystemClock.uptimeMillis();
- }
+ app.lastActivityTime = SystemClock.uptimeMillis();
if (app.activities.size() > 0) {
// If this process has activities, we more strongly want to keep
// it around.
@@ -1863,24 +1860,22 @@ public final class ActivityManagerService extends ActivityManagerNative
if (cr.binding != null && cr.binding.service != null
&& cr.binding.service.app != null
&& cr.binding.service.app.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cr.binding.service.app,
- updateActivityTime, i+1);
+ updateLruProcessInternalLocked(cr.binding.service.app, i+1);
}
}
}
for (int j=app.conProviders.size()-1; j>=0; j--) {
ContentProviderRecord cpr = app.conProviders.get(j).provider;
if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cpr.proc,
- updateActivityTime, i+1);
+ updateLruProcessInternalLocked(cpr.proc, i+1);
}
}
}
final void updateLruProcessLocked(ProcessRecord app,
- boolean oomAdj, boolean updateActivityTime) {
+ boolean oomAdj) {
mLruSeq++;
- updateLruProcessInternalLocked(app, updateActivityTime, 0);
+ updateLruProcessInternalLocked(app, 0);
//Slog.i(TAG, "Putting proc to front: " + app.processName);
if (oomAdj) {
@@ -1981,7 +1976,8 @@ public final class ActivityManagerService extends ActivityManagerNative
+ "/" + info.processName);
mProcessCrashTimes.remove(info.processName, info.uid);
if (mBadProcesses.get(info.processName, info.uid) != null) {
- EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
+ EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
+ UserHandle.getUserId(info.uid), info.uid,
info.processName);
mBadProcesses.remove(info.processName, info.uid);
if (app != null) {
@@ -2129,7 +2125,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
+ EventLog.writeEvent(EventLogTags.AM_PROC_START,
+ UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");
@@ -2946,7 +2943,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!r.finishing) {
Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
- System.identityHashCode(r),
+ r.userId, System.identityHashCode(r),
r.task.taskId, r.shortComponentName,
"proc died without state saved");
}
@@ -3037,7 +3034,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
+ ") has died.");
}
- EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
if (localLOGV) Slog.v(
TAG, "Dying app: " + app + ", pid: " + pid
+ ", thread: " + thread.asBinder());
@@ -3086,7 +3083,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// A new process has already been started.
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
+ ") has died and restarted (pid " + app.pid + ").");
- EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
} else if (DEBUG_PROCESSES) {
Slog.d(TAG, "Received spurious death notification for thread "
+ thread.asBinder());
@@ -3321,8 +3318,8 @@ public final class ActivityManagerService extends ActivityManagerNative
app.notResponding = true;
// Log the ANR to the event log.
- EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
- annotation);
+ EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
+ app.processName, app.info.flags, annotation);
// Dump thread traces as quickly as we can, starting with "interesting" processes.
firstPids.add(app.pid);
@@ -3408,7 +3405,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Slog.w(TAG, "Killing " + app + ": background ANR");
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "background ANR");
Process.killProcessQuiet(app.pid);
return;
@@ -4077,8 +4074,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (gone) {
Slog.w(TAG, "Process " + app + " failed to attach");
- EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
- app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
+ pid, app.uid, app.processName);
mProcessNames.remove(app.processName, app.uid);
mIsolatedProcesses.remove(app.uid);
if (mHeavyWeightProcess == app) {
@@ -4090,7 +4087,7 @@ public final class ActivityManagerService extends ActivityManagerNative
checkAppInLaunchingProvidersLocked(app, true);
// Take care of any services that are waiting for the process.
mServices.processStartTimedOutLocked(app);
- EventLog.writeEvent(EventLogTags.AM_KILL, pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
app.processName, app.setAdj, "start timeout");
Process.killProcessQuiet(pid);
if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
@@ -4166,7 +4163,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return false;
}
- EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
+ EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
app.thread = thread;
app.curAdj = app.setAdj = -100;
@@ -4244,7 +4241,7 @@ public final class ActivityManagerService extends ActivityManagerNative
enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
- updateLruProcessLocked(app, false, true);
+ updateLruProcessLocked(app, false);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
// todo: Yikes! What should we do? For now we will try to
@@ -5914,7 +5911,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ProcessRecord pr = procs.get(i);
if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
- EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
pr.processName, pr.setAdj, "remove task");
pr.killedBackground = true;
Process.killProcessQuiet(pr.pid);
@@ -6442,7 +6439,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// make sure to count it as being accessed and thus
// back up on the LRU list. This is good because
// content providers are often expensive to start.
- updateLruProcessLocked(cpr.proc, false, true);
+ updateLruProcessLocked(cpr.proc, false);
}
}
@@ -6630,6 +6627,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ cpi.applicationInfo.uid + " for provider "
+ name + ": launching app became null");
EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
+ UserHandle.getUserId(cpi.applicationInfo.uid),
cpi.applicationInfo.packageName,
cpi.applicationInfo.uid, name);
return null;
@@ -7013,7 +7011,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
- updateLruProcessLocked(app, true, true);
+ updateLruProcessLocked(app, true);
}
// This package really, really can not be stopped.
@@ -7499,7 +7497,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int adj = proc.setAdj;
if (adj >= worstType && !proc.killedBackground) {
Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
- EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
proc.processName, adj, reason);
killed = true;
proc.killedBackground = true;
@@ -7535,8 +7533,8 @@ public final class ActivityManagerService extends ActivityManagerNative
final int adj = proc.setAdj;
if (adj > belowAdj && !proc.killedBackground) {
Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
- EventLog.writeEvent(
- EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
+ EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
+ proc.pid, proc.processName, adj, reason);
killed = true;
proc.killedBackground = true;
Process.killProcessQuiet(pid);
@@ -7953,7 +7951,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.pid > 0 && app.pid != MY_PID) {
handleAppCrashLocked(app);
Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "user's request after error");
Process.killProcessQuiet(app.pid);
}
@@ -7978,7 +7976,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Process " + app.info.processName
+ " has crashed too many times: killing!");
EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
- app.info.processName, app.uid);
+ app.userId, app.info.processName, app.uid);
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
if (r.app == app) {
@@ -7993,7 +7991,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// explicitly does so... but for persistent process, we really
// need to keep it running. If a persistent process is actually
// repeatedly crashing, then badness for everyone.
- EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
+ EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
app.info.processName);
if (!app.isolated) {
// XXX We don't have a way to mark isolated processes
@@ -8106,7 +8104,7 @@ public final class ActivityManagerService extends ActivityManagerNative
: (r == null ? "unknown" : r.processName);
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
- processName,
+ UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
@@ -8304,7 +8302,8 @@ public final class ActivityManagerService extends ActivityManagerNative
final String processName = app == null ? "system_server"
: (r == null ? "unknown" : r.processName);
- EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
+ EventLog.writeEvent(EventLogTags.AM_WTF,
+ UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
processName,
r == null ? -1 : r.info.flags,
tag, crashInfo.exceptionMessage);
@@ -10067,6 +10066,7 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.print(" ");
pw.print("oom: max="); pw.print(r.maxAdj);
pw.print(" hidden="); pw.print(r.hiddenAdj);
+ pw.print(" client="); pw.print(r.clientHiddenAdj);
pw.print(" empty="); pw.print(r.emptyAdj);
pw.print(" curRaw="); pw.print(r.curRawAdj);
pw.print(" setRaw="); pw.print(r.setRawAdj);
@@ -10591,7 +10591,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG, "Kill " + capp.processName
+ " (pid " + capp.pid + "): provider " + cpr.info.name
+ " in dying process " + (proc != null ? proc.processName : "??"));
- EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
capp.processName, capp.setAdj, "dying provider "
+ cpr.name.toShortString());
Process.killProcessQuiet(capp.pid);
@@ -12466,7 +12466,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
}
- private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
+ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
if (mAdjSeq == app.adjSeq) {
// This adjustment has already been computed. If we are calling
@@ -12474,8 +12474,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// an earlier hidden adjustment that isn't really for us... if
// so, use the new hidden adjustment.
if (!recursed && app.hidden) {
- app.curAdj = app.curRawAdj = app.nonStoppingAdj =
- app.hasActivities ? hiddenAdj : emptyAdj;
+ if (app.hasActivities) {
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
+ } else if (app.hasClientActivities) {
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
+ } else {
+ app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
+ }
}
return app.curRawAdj;
}
@@ -12491,6 +12496,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjTarget = null;
app.empty = false;
app.hidden = false;
+ app.hasClientActivities = false;
final int activitiesSize = app.activities.size();
@@ -12572,7 +12578,7 @@ public final class ActivityManagerService extends ActivityManagerNative
adj = hiddenAdj;
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.hidden = true;
- app.adjType = "bg-activities";
+ app.adjType = "bg-act";
}
boolean hasStoppingActivities = false;
@@ -12614,11 +12620,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (adj == hiddenAdj && !app.hasActivities) {
- // Whoops, this process is completely empty as far as we know
- // at this point.
- adj = emptyAdj;
- app.empty = true;
- app.adjType = "bg-empty";
+ if (app.hasClientActivities) {
+ adj = clientHiddenAdj;
+ app.adjType = "bg-client-act";
+ } else {
+ // Whoops, this process is completely empty as far as we know
+ // at this point.
+ adj = emptyAdj;
+ app.empty = true;
+ app.adjType = "bg-empty";
+ }
}
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -12626,13 +12637,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.hidden = false;
- app.adjType = "foreground-service";
+ app.adjType = "fg-service";
schedGroup = Process.THREAD_GROUP_DEFAULT;
} else if (app.forcingToForeground != null) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
app.hidden = false;
- app.adjType = "force-foreground";
+ app.adjType = "force-fg";
app.adjSource = app.forcingToForeground;
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
@@ -12754,6 +12765,14 @@ public final class ActivityManagerService extends ActivityManagerNative
myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
}
}
+ int myClientHiddenAdj = clientHiddenAdj;
+ if (myClientHiddenAdj > client.clientHiddenAdj) {
+ if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
+ myClientHiddenAdj = client.clientHiddenAdj;
+ } else {
+ myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
+ }
+ }
int myEmptyAdj = emptyAdj;
if (myEmptyAdj > client.emptyAdj) {
if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
@@ -12763,7 +12782,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myEmptyAdj, TOP_APP, true, doingAll);
+ myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
String adjType = null;
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
// Not doing bind OOM management, so treat
@@ -12792,6 +12811,19 @@ public final class ActivityManagerService extends ActivityManagerNative
clientAdj = adj;
}
}
+ } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
+ if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
+ // If this connection is keeping the service
+ // created, then we want to try to better follow
+ // its memory management semantics for activities.
+ // That is, if it is sitting in the background
+ // LRU list as a hidden process (with activities),
+ // we don't want the service it is connected to
+ // to go into the empty LRU and quickly get killed,
+ // because I'll we'll do is just end up restarting
+ // the service.
+ app.hasClientActivities |= client.hasActivities;
+ }
}
if (adj > clientAdj) {
// If this process has recently shown UI, and
@@ -12843,8 +12875,8 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
+ final ActivityRecord a = cr.activity;
if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
- ActivityRecord a = cr.activity;
if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
(a.visible || a.state == ActivityState.RESUMED
|| a.state == ActivityState.PAUSING)) {
@@ -12902,6 +12934,14 @@ public final class ActivityManagerService extends ActivityManagerNative
myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
}
}
+ int myClientHiddenAdj = clientHiddenAdj;
+ if (myClientHiddenAdj > client.clientHiddenAdj) {
+ if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+ myClientHiddenAdj = client.clientHiddenAdj;
+ } else {
+ myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
+ }
+ }
int myEmptyAdj = emptyAdj;
if (myEmptyAdj > client.emptyAdj) {
if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
@@ -12911,7 +12951,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
- myEmptyAdj, TOP_APP, true, doingAll);
+ myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
if (adj > clientAdj) {
if (app.hasShownUi && app != mHomeProcess
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -13301,7 +13341,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Excessive wake lock in " + app.processName
+ " (pid " + app.pid + "): held " + wtimeUsed
+ " during " + realtimeSince);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "excessive wake lock");
Process.killProcessQuiet(app.pid);
} else if (doCpuKills && uptimeSince > 0
@@ -13313,7 +13353,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, "Excessive CPU in " + app.processName
+ " (pid " + app.pid + "): used " + cputimeUsed
+ " during " + uptimeSince);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "excessive cpu");
Process.killProcessQuiet(app.pid);
} else {
@@ -13325,8 +13365,9 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
- int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
+ int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
app.hiddenAdj = hiddenAdj;
+ app.clientHiddenAdj = clientHiddenAdj;
app.emptyAdj = emptyAdj;
if (app.thread == null) {
@@ -13337,7 +13378,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean success = true;
- computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
+ computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
if (app.curRawAdj != app.setRawAdj) {
if (wasKeeping && !app.keeping) {
@@ -13374,7 +13415,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (app.waitingToKill != null &&
app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, app.waitingToKill);
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
@@ -13424,8 +13465,8 @@ public final class ActivityManagerService extends ActivityManagerNative
mAdjSeq++;
- boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
- TOP_APP, false);
+ boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
+ app.emptyAdj, TOP_APP, false);
final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
&& app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
if (nowHidden != wasHidden) {
@@ -13439,6 +13480,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final void updateOomAdjLocked() {
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
+ final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
if (false) {
RuntimeException e = new RuntimeException();
@@ -13449,20 +13491,40 @@ public final class ActivityManagerService extends ActivityManagerNative
mAdjSeq++;
mNewNumServiceProcs = 0;
+ final int emptyProcessLimit;
+ final int hiddenProcessLimit;
+ if (mProcessLimit <= 0) {
+ emptyProcessLimit = hiddenProcessLimit = 0;
+ } else if (mProcessLimit == 1) {
+ emptyProcessLimit = 1;
+ hiddenProcessLimit = 0;
+ } else {
+ emptyProcessLimit = (mProcessLimit*2)/3;
+ hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
+ }
+
// Let's determine how many processes we have running vs.
// how many slots we have for background processes; we may want
// to put multiple processes in a slot of there are enough of
// them.
int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
- ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
- int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
+ int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
+ if (numEmptyProcs > hiddenProcessLimit) {
+ // If there are more empty processes than our limit on hidden
+ // processes, then use the hidden process limit for the factor.
+ // This ensures that the really old empty processes get pushed
+ // down to the bottom, so if we are running low on memory we will
+ // have a better chance at keeping around more hidden processes
+ // instead of a gazillion empty processes.
+ numEmptyProcs = hiddenProcessLimit;
+ }
+ int emptyFactor = numEmptyProcs/numSlots;
if (emptyFactor < 1) emptyFactor = 1;
int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
if (hiddenFactor < 1) hiddenFactor = 1;
int stepHidden = 0;
int stepEmpty = 0;
- final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
- final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
int numHidden = 0;
int numEmpty = 0;
int numTrimming = 0;
@@ -13477,11 +13539,12 @@ public final class ActivityManagerService extends ActivityManagerNative
int nextHiddenAdj = curHiddenAdj+1;
int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
int nextEmptyAdj = curEmptyAdj+2;
+ int curClientHiddenAdj = curEmptyAdj;
while (i > 0) {
i--;
ProcessRecord app = mLruProcesses.get(i);
//Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
- updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
+ updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
if (!app.killedBackground) {
if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
// This process was assigned as a hidden process... step the
@@ -13496,17 +13559,31 @@ public final class ActivityManagerService extends ActivityManagerNative
if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
}
+ if (curClientHiddenAdj <= curHiddenAdj) {
+ curClientHiddenAdj = curHiddenAdj + 1;
+ if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
+ curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ }
+ }
}
}
numHidden++;
if (numHidden > hiddenProcessLimit) {
Slog.i(TAG, "No longer want " + app.processName
+ " (pid " + app.pid + "): hidden #" + numHidden);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "too many background");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
}
+ } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
+ // This process has a client that has activities. We will have
+ // given it the current hidden adj; here we will just leave it
+ // without stepping the hidden adj.
+ curClientHiddenAdj++;
+ if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
+ curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+ }
} else {
if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
// This process was assigned as an empty process... step the
@@ -13525,15 +13602,28 @@ public final class ActivityManagerService extends ActivityManagerNative
} else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
mNumNonHiddenProcs++;
}
- if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
- numEmpty++;
- if (numEmpty > emptyProcessLimit) {
+ if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
+ && !app.hasClientActivities) {
+ if (numEmpty > ProcessList.TRIM_EMPTY_APPS
+ && app.lastActivityTime < oldTime) {
Slog.i(TAG, "No longer want " + app.processName
- + " (pid " + app.pid + "): empty #" + numEmpty);
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
- app.processName, app.setAdj, "too many background");
+ + " (pid " + app.pid + "): empty for "
+ + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
+ / 1000) + "s");
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
+ app.processName, app.setAdj, "old background process");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
+ } else {
+ numEmpty++;
+ if (numEmpty > emptyProcessLimit) {
+ Slog.i(TAG, "No longer want " + app.processName
+ + " (pid " + app.pid + "): empty #" + numEmpty);
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
+ app.processName, app.setAdj, "too many background");
+ app.killedBackground = true;
+ Process.killProcessQuiet(app.pid);
+ }
}
}
}
@@ -13546,7 +13636,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// left sitting around after no longer needed.
Slog.i(TAG, "Isolated process " + app.processName
+ " (pid " + app.pid + ") no longer needed");
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "isolated not needed");
app.killedBackground = true;
Process.killProcessQuiet(app.pid);
@@ -13567,8 +13657,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// 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.
- if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
- && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
+ if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
+ && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
final int numHiddenAndEmpty = numHidden + numEmpty;
final int N = mLruProcesses.size();
int factor = numTrimming/3;
@@ -13578,9 +13668,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (factor < minFactor) factor = minFactor;
int step = 0;
int fgTrimLevel;
- if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
+ if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
- } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
+ } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
} else {
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
@@ -13700,7 +13790,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ (app.thread != null ? app.thread.asBinder() : null)
+ ")\n");
if (app.pid > 0 && app.pid != MY_PID) {
- EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
app.processName, app.setAdj, "empty");
Process.killProcessQuiet(app.pid);
} else {