am 1866f68d: Merge "Modify how the background process LRU list is handled." into jb-mr1-dev
* commit '1866f68dfe35da46995e5f2321f33e8fee44bcf8': Modify how the background process LRU list is handled.
This commit is contained in:
@@ -685,6 +685,18 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
*/
|
*/
|
||||||
int mLruSeq = 0;
|
int mLruSeq = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of the non-hidden/empty process we last found, to help
|
||||||
|
* determine how to distribute hidden/empty processes next time.
|
||||||
|
*/
|
||||||
|
int mNumNonHiddenProcs = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of the number of hidden procs, to balance oom adj
|
||||||
|
* distribution between those and empty procs.
|
||||||
|
*/
|
||||||
|
int mNumHiddenProcs = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of the number of service processes we last found, to
|
* Keep track of the number of service processes we last found, to
|
||||||
* determine on the next iteration which should be B services.
|
* determine on the next iteration which should be B services.
|
||||||
@@ -9081,7 +9093,9 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
|
pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
|
||||||
pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
|
pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
|
||||||
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
|
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
|
||||||
pw.println(" mNumServiceProcs=" + mNumServiceProcs
|
pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
|
||||||
|
+ " mNumHiddenProcs=" + mNumHiddenProcs
|
||||||
|
+ " mNumServiceProcs=" + mNumServiceProcs
|
||||||
+ " mNewNumServiceProcs=" + mNewNumServiceProcs);
|
+ " mNewNumServiceProcs=" + mNewNumServiceProcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9746,6 +9760,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
pw.print(" ");
|
pw.print(" ");
|
||||||
pw.print("oom: max="); pw.print(r.maxAdj);
|
pw.print("oom: max="); pw.print(r.maxAdj);
|
||||||
pw.print(" hidden="); pw.print(r.hiddenAdj);
|
pw.print(" hidden="); pw.print(r.hiddenAdj);
|
||||||
|
pw.print(" empty="); pw.print(r.emptyAdj);
|
||||||
pw.print(" curRaw="); pw.print(r.curRawAdj);
|
pw.print(" curRaw="); pw.print(r.curRawAdj);
|
||||||
pw.print(" setRaw="); pw.print(r.setRawAdj);
|
pw.print(" setRaw="); pw.print(r.setRawAdj);
|
||||||
pw.print(" cur="); pw.print(r.curAdj);
|
pw.print(" cur="); pw.print(r.curAdj);
|
||||||
@@ -11966,14 +11981,15 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
|
private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
|
||||||
ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
|
int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
|
||||||
if (mAdjSeq == app.adjSeq) {
|
if (mAdjSeq == app.adjSeq) {
|
||||||
// This adjustment has already been computed. If we are calling
|
// This adjustment has already been computed. If we are calling
|
||||||
// from the top, we may have already computed our adjustment with
|
// from the top, we may have already computed our adjustment with
|
||||||
// an earlier hidden adjustment that isn't really for us... if
|
// an earlier hidden adjustment that isn't really for us... if
|
||||||
// so, use the new hidden adjustment.
|
// so, use the new hidden adjustment.
|
||||||
if (!recursed && app.hidden) {
|
if (!recursed && app.hidden) {
|
||||||
app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
|
app.curAdj = app.curRawAdj = app.nonStoppingAdj =
|
||||||
|
app.hasActivities ? hiddenAdj : emptyAdj;
|
||||||
}
|
}
|
||||||
return app.curRawAdj;
|
return app.curRawAdj;
|
||||||
}
|
}
|
||||||
@@ -11981,7 +11997,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
if (app.thread == null) {
|
if (app.thread == null) {
|
||||||
app.adjSeq = mAdjSeq;
|
app.adjSeq = mAdjSeq;
|
||||||
app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
|
app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
|
||||||
return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
|
return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
|
app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
|
||||||
@@ -11998,6 +12014,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
app.adjType = "fixed";
|
app.adjType = "fixed";
|
||||||
app.adjSeq = mAdjSeq;
|
app.adjSeq = mAdjSeq;
|
||||||
app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
|
app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
|
||||||
|
app.hasActivities = false;
|
||||||
app.foregroundActivities = false;
|
app.foregroundActivities = false;
|
||||||
app.keeping = true;
|
app.keeping = true;
|
||||||
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
|
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
|
||||||
@@ -12008,12 +12025,15 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
app.systemNoUi = true;
|
app.systemNoUi = true;
|
||||||
if (app == TOP_APP) {
|
if (app == TOP_APP) {
|
||||||
app.systemNoUi = false;
|
app.systemNoUi = false;
|
||||||
|
app.hasActivities = true;
|
||||||
} else if (activitiesSize > 0) {
|
} else if (activitiesSize > 0) {
|
||||||
for (int j = 0; j < activitiesSize; j++) {
|
for (int j = 0; j < activitiesSize; j++) {
|
||||||
final ActivityRecord r = app.activities.get(j);
|
final ActivityRecord r = app.activities.get(j);
|
||||||
if (r.visible) {
|
if (r.visible) {
|
||||||
app.systemNoUi = false;
|
app.systemNoUi = false;
|
||||||
break;
|
}
|
||||||
|
if (r.app == app) {
|
||||||
|
app.hasActivities = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12022,6 +12042,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
|
|
||||||
app.keeping = false;
|
app.keeping = false;
|
||||||
app.systemNoUi = false;
|
app.systemNoUi = false;
|
||||||
|
app.hasActivities = false;
|
||||||
|
|
||||||
// Determine the importance of the process, starting with most
|
// Determine the importance of the process, starting with most
|
||||||
// important to least, and assign an appropriate OOM adjustment.
|
// important to least, and assign an appropriate OOM adjustment.
|
||||||
@@ -12037,6 +12058,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
app.adjType = "top-activity";
|
app.adjType = "top-activity";
|
||||||
foregroundActivities = true;
|
foregroundActivities = true;
|
||||||
interesting = true;
|
interesting = true;
|
||||||
|
app.hasActivities = true;
|
||||||
} else if (app.instrumentationClass != null) {
|
} else if (app.instrumentationClass != null) {
|
||||||
// Don't want to kill running instrumentation.
|
// Don't want to kill running instrumentation.
|
||||||
adj = ProcessList.FOREGROUND_APP_ADJ;
|
adj = ProcessList.FOREGROUND_APP_ADJ;
|
||||||
@@ -12058,21 +12080,13 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
adj = ProcessList.FOREGROUND_APP_ADJ;
|
adj = ProcessList.FOREGROUND_APP_ADJ;
|
||||||
schedGroup = Process.THREAD_GROUP_DEFAULT;
|
schedGroup = Process.THREAD_GROUP_DEFAULT;
|
||||||
app.adjType = "exec-service";
|
app.adjType = "exec-service";
|
||||||
} else if (activitiesSize > 0) {
|
} else {
|
||||||
// This app is in the background with paused activities.
|
// Assume process is hidden (has activities); we will correct
|
||||||
// We inspect activities to potentially upgrade adjustment further below.
|
// later if this is not the case.
|
||||||
adj = hiddenAdj;
|
adj = hiddenAdj;
|
||||||
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
|
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
|
||||||
app.hidden = true;
|
app.hidden = true;
|
||||||
app.adjType = "bg-activities";
|
app.adjType = "bg-activities";
|
||||||
} else {
|
|
||||||
// A very not-needed process. If this is lower in the lru list,
|
|
||||||
// we will push it in to the empty bucket.
|
|
||||||
adj = hiddenAdj;
|
|
||||||
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
|
|
||||||
app.hidden = true;
|
|
||||||
app.empty = true;
|
|
||||||
app.adjType = "bg-empty";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasStoppingActivities = false;
|
boolean hasStoppingActivities = false;
|
||||||
@@ -12089,6 +12103,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
schedGroup = Process.THREAD_GROUP_DEFAULT;
|
schedGroup = Process.THREAD_GROUP_DEFAULT;
|
||||||
app.hidden = false;
|
app.hidden = false;
|
||||||
|
app.hasActivities = true;
|
||||||
foregroundActivities = true;
|
foregroundActivities = true;
|
||||||
break;
|
break;
|
||||||
} else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
|
} else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
|
||||||
@@ -12106,9 +12121,20 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
foregroundActivities = true;
|
foregroundActivities = true;
|
||||||
hasStoppingActivities = true;
|
hasStoppingActivities = true;
|
||||||
}
|
}
|
||||||
|
if (r.app == app) {
|
||||||
|
app.hasActivities = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
|
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
|
||||||
if (app.foregroundServices) {
|
if (app.foregroundServices) {
|
||||||
// The user is aware of this app, so make it visible.
|
// The user is aware of this app, so make it visible.
|
||||||
@@ -12242,8 +12268,16 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
|
myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clientAdj = computeOomAdjLocked(
|
int myEmptyAdj = emptyAdj;
|
||||||
client, myHiddenAdj, TOP_APP, true, doingAll);
|
if (myEmptyAdj > client.emptyAdj) {
|
||||||
|
if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
|
||||||
|
myEmptyAdj = client.emptyAdj;
|
||||||
|
} else {
|
||||||
|
myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clientAdj = computeOomAdjLocked(client, myHiddenAdj,
|
||||||
|
myEmptyAdj, TOP_APP, true, doingAll);
|
||||||
String adjType = null;
|
String adjType = null;
|
||||||
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
|
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
|
||||||
// Not doing bind OOM management, so treat
|
// Not doing bind OOM management, so treat
|
||||||
@@ -12382,8 +12416,16 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
|
myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int clientAdj = computeOomAdjLocked(
|
int myEmptyAdj = emptyAdj;
|
||||||
client, myHiddenAdj, TOP_APP, true, doingAll);
|
if (myEmptyAdj > client.emptyAdj) {
|
||||||
|
if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
|
||||||
|
myEmptyAdj = client.emptyAdj;
|
||||||
|
} else {
|
||||||
|
myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
|
||||||
|
myEmptyAdj, TOP_APP, true, doingAll);
|
||||||
if (adj > clientAdj) {
|
if (adj > clientAdj) {
|
||||||
if (app.hasShownUi && app != mHomeProcess
|
if (app.hasShownUi && app != mHomeProcess
|
||||||
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
|
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
|
||||||
@@ -12796,9 +12838,10 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean updateOomAdjLocked(
|
private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
|
||||||
ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
|
int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
|
||||||
app.hiddenAdj = hiddenAdj;
|
app.hiddenAdj = hiddenAdj;
|
||||||
|
app.emptyAdj = emptyAdj;
|
||||||
|
|
||||||
if (app.thread == null) {
|
if (app.thread == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -12808,7 +12851,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
|
|
||||||
boolean success = true;
|
boolean success = true;
|
||||||
|
|
||||||
computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
|
computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
|
||||||
|
|
||||||
if (app.curRawAdj != app.setRawAdj) {
|
if (app.curRawAdj != app.setRawAdj) {
|
||||||
if (wasKeeping && !app.keeping) {
|
if (wasKeeping && !app.keeping) {
|
||||||
@@ -12895,7 +12938,8 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
|
|
||||||
mAdjSeq++;
|
mAdjSeq++;
|
||||||
|
|
||||||
boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
|
boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
|
||||||
|
TOP_APP, false);
|
||||||
final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
|
final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
|
||||||
&& app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
|
&& app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
|
||||||
if (nowHidden != wasHidden) {
|
if (nowHidden != wasHidden) {
|
||||||
@@ -12923,34 +12967,53 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
// how many slots we have for background processes; we may want
|
// how many slots we have for background processes; we may want
|
||||||
// to put multiple processes in a slot of there are enough of
|
// to put multiple processes in a slot of there are enough of
|
||||||
// them.
|
// them.
|
||||||
int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
|
int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
|
||||||
int factor = (mLruProcesses.size()-4)/numSlots;
|
- ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
|
||||||
if (factor < 1) factor = 1;
|
int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
|
||||||
int step = 0;
|
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 numHidden = 0;
|
||||||
|
int numEmpty = 0;
|
||||||
int numTrimming = 0;
|
int numTrimming = 0;
|
||||||
|
|
||||||
|
mNumNonHiddenProcs = 0;
|
||||||
|
mNumHiddenProcs = 0;
|
||||||
|
|
||||||
// First update the OOM adjustment for each of the
|
// First update the OOM adjustment for each of the
|
||||||
// application processes based on their current state.
|
// application processes based on their current state.
|
||||||
int i = mLruProcesses.size();
|
int i = mLruProcesses.size();
|
||||||
int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
|
int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
|
||||||
|
int nextHiddenAdj = curHiddenAdj+1;
|
||||||
|
int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
|
||||||
|
int nextEmptyAdj = curEmptyAdj+2;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
i--;
|
i--;
|
||||||
ProcessRecord app = mLruProcesses.get(i);
|
ProcessRecord app = mLruProcesses.get(i);
|
||||||
//Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
|
//Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
|
||||||
updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
|
updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
|
||||||
if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
|
|
||||||
&& app.curAdj == curHiddenAdj) {
|
|
||||||
step++;
|
|
||||||
if (step >= factor) {
|
|
||||||
step = 0;
|
|
||||||
curHiddenAdj++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!app.killedBackground) {
|
if (!app.killedBackground) {
|
||||||
if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
|
if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
|
||||||
|
// This process was assigned as a hidden process... step the
|
||||||
|
// hidden level.
|
||||||
|
mNumHiddenProcs++;
|
||||||
|
if (curHiddenAdj != nextHiddenAdj) {
|
||||||
|
stepHidden++;
|
||||||
|
if (stepHidden >= hiddenFactor) {
|
||||||
|
stepHidden = 0;
|
||||||
|
curHiddenAdj = nextHiddenAdj;
|
||||||
|
nextHiddenAdj += 2;
|
||||||
|
if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
|
||||||
|
nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
numHidden++;
|
numHidden++;
|
||||||
if (numHidden > mProcessLimit) {
|
if (numHidden > hiddenProcessLimit) {
|
||||||
Slog.i(TAG, "No longer want " + app.processName
|
Slog.i(TAG, "No longer want " + app.processName
|
||||||
+ " (pid " + app.pid + "): hidden #" + numHidden);
|
+ " (pid " + app.pid + "): hidden #" + numHidden);
|
||||||
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
|
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
|
||||||
@@ -12958,8 +13021,37 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
app.killedBackground = true;
|
app.killedBackground = true;
|
||||||
Process.killProcessQuiet(app.pid);
|
Process.killProcessQuiet(app.pid);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
|
||||||
|
// This process was assigned as an empty process... step the
|
||||||
|
// empty level.
|
||||||
|
if (curEmptyAdj != nextEmptyAdj) {
|
||||||
|
stepEmpty++;
|
||||||
|
if (stepEmpty >= emptyFactor) {
|
||||||
|
stepEmpty = 0;
|
||||||
|
curEmptyAdj = nextEmptyAdj;
|
||||||
|
nextEmptyAdj += 2;
|
||||||
|
if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
|
||||||
|
nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
|
||||||
|
mNumNonHiddenProcs++;
|
||||||
|
}
|
||||||
|
if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
|
||||||
|
numEmpty++;
|
||||||
|
if (numEmpty > emptyProcessLimit) {
|
||||||
|
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");
|
||||||
|
app.killedBackground = true;
|
||||||
|
Process.killProcessQuiet(app.pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
|
if (app.isolated && app.services.size() <= 0) {
|
||||||
// If this is an isolated process, and there are no
|
// If this is an isolated process, and there are no
|
||||||
// services running in it, then the process is no longer
|
// services running in it, then the process is no longer
|
||||||
// needed. We agressively kill these because we can by
|
// needed. We agressively kill these because we can by
|
||||||
@@ -12989,18 +13081,20 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
// are managing to keep around is less than half the maximum we desire;
|
// 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
|
// if we are keeping a good number around, we'll let them use whatever
|
||||||
// memory they want.
|
// memory they want.
|
||||||
if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
|
if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
|
||||||
|
&& numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
|
||||||
|
final int numHiddenAndEmpty = numHidden + numEmpty;
|
||||||
final int N = mLruProcesses.size();
|
final int N = mLruProcesses.size();
|
||||||
factor = numTrimming/3;
|
int factor = numTrimming/3;
|
||||||
int minFactor = 2;
|
int minFactor = 2;
|
||||||
if (mHomeProcess != null) minFactor++;
|
if (mHomeProcess != null) minFactor++;
|
||||||
if (mPreviousProcess != null) minFactor++;
|
if (mPreviousProcess != null) minFactor++;
|
||||||
if (factor < minFactor) factor = minFactor;
|
if (factor < minFactor) factor = minFactor;
|
||||||
step = 0;
|
int step = 0;
|
||||||
int fgTrimLevel;
|
int fgTrimLevel;
|
||||||
if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
|
if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
|
||||||
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
|
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
|
||||||
} else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
|
} else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
|
||||||
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
|
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
|
||||||
} else {
|
} else {
|
||||||
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
|
fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ class ProcessRecord {
|
|||||||
long lruWeight; // Weight for ordering in LRU list
|
long lruWeight; // Weight for ordering in LRU list
|
||||||
int maxAdj; // Maximum OOM adjustment for this process
|
int maxAdj; // Maximum OOM adjustment for this process
|
||||||
int hiddenAdj; // If hidden, this is the adjustment to use
|
int hiddenAdj; // If hidden, this is the adjustment to use
|
||||||
|
int emptyAdj; // If empty, this is the adjustment to use
|
||||||
int curRawAdj; // Current OOM unlimited adjustment for this process
|
int curRawAdj; // Current OOM unlimited adjustment for this process
|
||||||
int setRawAdj; // Last set OOM unlimited adjustment for this process
|
int setRawAdj; // Last set OOM unlimited adjustment for this process
|
||||||
int nonStoppingAdj; // Adjustment not counting any stopping activities
|
int nonStoppingAdj; // Adjustment not counting any stopping activities
|
||||||
@@ -73,6 +74,7 @@ class ProcessRecord {
|
|||||||
boolean serviceb; // Process currently is on the service B list
|
boolean serviceb; // Process currently is on the service B list
|
||||||
boolean keeping; // Actively running code so don't kill due to that?
|
boolean keeping; // Actively running code so don't kill due to that?
|
||||||
boolean setIsForeground; // Running foreground UI when last set?
|
boolean setIsForeground; // Running foreground UI when last set?
|
||||||
|
boolean hasActivities; // Are there any activities running in this process?
|
||||||
boolean foregroundServices; // Running any services that are foreground?
|
boolean foregroundServices; // Running any services that are foreground?
|
||||||
boolean foregroundActivities; // Running any activities that are foreground?
|
boolean foregroundActivities; // Running any activities that are foreground?
|
||||||
boolean systemNoUi; // This is a system process, but not currently showing UI.
|
boolean systemNoUi; // This is a system process, but not currently showing UI.
|
||||||
@@ -199,6 +201,7 @@ class ProcessRecord {
|
|||||||
pw.print(" empty="); pw.println(empty);
|
pw.print(" empty="); pw.println(empty);
|
||||||
pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
|
pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
|
||||||
pw.print(" hidden="); pw.print(hiddenAdj);
|
pw.print(" hidden="); pw.print(hiddenAdj);
|
||||||
|
pw.print(" empty="); pw.print(emptyAdj);
|
||||||
pw.print(" curRaw="); pw.print(curRawAdj);
|
pw.print(" curRaw="); pw.print(curRawAdj);
|
||||||
pw.print(" setRaw="); pw.print(setRawAdj);
|
pw.print(" setRaw="); pw.print(setRawAdj);
|
||||||
pw.print(" nonStopping="); pw.print(nonStoppingAdj);
|
pw.print(" nonStopping="); pw.print(nonStoppingAdj);
|
||||||
@@ -215,7 +218,9 @@ class ProcessRecord {
|
|||||||
pw.print(" foregroundServices="); pw.print(foregroundServices);
|
pw.print(" foregroundServices="); pw.print(foregroundServices);
|
||||||
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
|
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
|
||||||
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
|
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
|
||||||
pw.print(" removed="); pw.println(removed);
|
pw.print(" removed="); pw.print(removed);
|
||||||
|
pw.print(" hasActivities="); pw.print(hasActivities);
|
||||||
|
pw.print(" foregroundActivities="); pw.println(foregroundActivities);
|
||||||
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
|
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
|
||||||
pw.print(" lruSeq="); pw.println(lruSeq);
|
pw.print(" lruSeq="); pw.println(lruSeq);
|
||||||
if (!keeping) {
|
if (!keeping) {
|
||||||
@@ -313,7 +318,7 @@ class ProcessRecord {
|
|||||||
pkgList.add(_info.packageName);
|
pkgList.add(_info.packageName);
|
||||||
thread = _thread;
|
thread = _thread;
|
||||||
maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
|
maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
|
||||||
hiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
|
hiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
|
||||||
curRawAdj = setRawAdj = -100;
|
curRawAdj = setRawAdj = -100;
|
||||||
curAdj = setAdj = -100;
|
curAdj = setAdj = -100;
|
||||||
persistent = false;
|
persistent = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user