Merge change 22883 into donut
* changes: Various tweaks to try to improve low memory behavior.
This commit is contained in:
@@ -1277,6 +1277,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
// TODO: we should ask the window manager to do something!
|
// TODO: we should ask the window manager to do something!
|
||||||
// for now we just do nothing
|
// for now we just do nothing
|
||||||
return;
|
return;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Log.e("ViewRoot", "IllegalArgumentException locking surface", e);
|
||||||
|
// TODO: we should ask the window manager to do something!
|
||||||
|
// for now we just do nothing
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.android.server;
|
|||||||
import com.android.server.am.ActivityManagerService;
|
import com.android.server.am.ActivityManagerService;
|
||||||
import com.android.server.status.StatusBarService;
|
import com.android.server.status.StatusBarService;
|
||||||
|
|
||||||
import dalvik.system.PathClassLoader;
|
|
||||||
import dalvik.system.VMRuntime;
|
import dalvik.system.VMRuntime;
|
||||||
|
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
@@ -32,7 +31,6 @@ import android.content.pm.IPackageManager;
|
|||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.media.AudioService;
|
import android.media.AudioService;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
@@ -46,9 +44,6 @@ import android.server.search.SearchManagerService;
|
|||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
class ServerThread extends Thread {
|
class ServerThread extends Thread {
|
||||||
private static final String TAG = "SystemServer";
|
private static final String TAG = "SystemServer";
|
||||||
private final static boolean INCLUDE_DEMO = false;
|
private final static boolean INCLUDE_DEMO = false;
|
||||||
|
|||||||
@@ -237,6 +237,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
// How long to wait after going idle before forcing apps to GC.
|
// How long to wait after going idle before forcing apps to GC.
|
||||||
static final int GC_TIMEOUT = 5*1000;
|
static final int GC_TIMEOUT = 5*1000;
|
||||||
|
|
||||||
|
// The minimum amount of time between successive GC requests for a process.
|
||||||
|
static final int GC_MIN_INTERVAL = 60*1000;
|
||||||
|
|
||||||
// How long we wait until giving up on an activity telling us it has
|
// How long we wait until giving up on an activity telling us it has
|
||||||
// finished destroying itself.
|
// finished destroying itself.
|
||||||
static final int DESTROY_TIMEOUT = 10*1000;
|
static final int DESTROY_TIMEOUT = 10*1000;
|
||||||
@@ -251,10 +254,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
// is no longer considered to be a relaunch of the service.
|
// is no longer considered to be a relaunch of the service.
|
||||||
static final int SERVICE_RESTART_DURATION = 5*1000;
|
static final int SERVICE_RESTART_DURATION = 5*1000;
|
||||||
|
|
||||||
|
// How long a service needs to be running until it will start back at
|
||||||
|
// SERVICE_RESTART_DURATION after being killed.
|
||||||
|
static final int SERVICE_RESET_RUN_DURATION = 60*1000;
|
||||||
|
|
||||||
|
// Multiplying factor to increase restart duration time by, for each time
|
||||||
|
// a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
|
||||||
|
static final int SERVICE_RESTART_DURATION_FACTOR = 4;
|
||||||
|
|
||||||
|
// The minimum amount of time between restarting services that we allow.
|
||||||
|
// That is, when multiple services are restarting, we won't allow each
|
||||||
|
// to restart less than this amount of time from the last one.
|
||||||
|
static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
|
||||||
|
|
||||||
// Maximum amount of time for there to be no activity on a service before
|
// Maximum amount of time for there to be no activity on a service before
|
||||||
// we consider it non-essential and allow its process to go on the
|
// we consider it non-essential and allow its process to go on the
|
||||||
// LRU background list.
|
// LRU background list.
|
||||||
static final int MAX_SERVICE_INACTIVITY = 10*60*1000;
|
static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
|
||||||
|
|
||||||
// How long we wait until we timeout on key dispatching.
|
// How long we wait until we timeout on key dispatching.
|
||||||
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
|
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
|
||||||
@@ -1090,8 +1106,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
}
|
|
||||||
case SHOW_UID_ERROR_MSG: {
|
case SHOW_UID_ERROR_MSG: {
|
||||||
// XXX This is a temporary dialog, no need to localize.
|
// XXX This is a temporary dialog, no need to localize.
|
||||||
AlertDialog d = new BaseErrorDialog(mContext);
|
AlertDialog d = new BaseErrorDialog(mContext);
|
||||||
@@ -1135,7 +1150,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
synchronized (ActivityManagerService.this) {
|
synchronized (ActivityManagerService.this) {
|
||||||
resumeTopActivityLocked(null);
|
resumeTopActivityLocked(null);
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
case PROC_START_TIMEOUT_MSG: {
|
case PROC_START_TIMEOUT_MSG: {
|
||||||
if (mDidDexOpt) {
|
if (mDidDexOpt) {
|
||||||
mDidDexOpt = false;
|
mDidDexOpt = false;
|
||||||
@@ -1148,12 +1163,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
synchronized (ActivityManagerService.this) {
|
synchronized (ActivityManagerService.this) {
|
||||||
processStartTimedOutLocked(app);
|
processStartTimedOutLocked(app);
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
|
case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
|
||||||
synchronized (ActivityManagerService.this) {
|
synchronized (ActivityManagerService.this) {
|
||||||
doPendingActivityLaunchesLocked(true);
|
doPendingActivityLaunchesLocked(true);
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
case KILL_APPLICATION_MSG: {
|
case KILL_APPLICATION_MSG: {
|
||||||
synchronized (ActivityManagerService.this) {
|
synchronized (ActivityManagerService.this) {
|
||||||
int uid = msg.arg1;
|
int uid = msg.arg1;
|
||||||
@@ -4426,17 +4441,26 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
if (!haveBg) {
|
if (!haveBg) {
|
||||||
Log.i(TAG, "Low Memory: No more background processes.");
|
Log.i(TAG, "Low Memory: No more background processes.");
|
||||||
EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
|
EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
|
||||||
|
long now = SystemClock.uptimeMillis();
|
||||||
for (i=0; i<count; i++) {
|
for (i=0; i<count; i++) {
|
||||||
ProcessRecord rec = mLRUProcesses.get(i);
|
ProcessRecord rec = mLRUProcesses.get(i);
|
||||||
if (rec.thread != null) {
|
if (rec.thread != null &&
|
||||||
rec.lastRequestedGc = SystemClock.uptimeMillis();
|
(rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
|
||||||
try {
|
// The low memory report is overriding any current
|
||||||
rec.thread.scheduleLowMemory();
|
// state for a GC request. Make sure to do
|
||||||
} catch (RemoteException e) {
|
// visible/foreground processes first.
|
||||||
// Don't care if the process is gone.
|
if (rec.setAdj <= VISIBLE_APP_ADJ) {
|
||||||
}
|
rec.lastRequestedGc = 0;
|
||||||
|
} else {
|
||||||
|
rec.lastRequestedGc = rec.lastLowMemory;
|
||||||
|
}
|
||||||
|
rec.reportLowMemory = true;
|
||||||
|
rec.lastLowMemory = now;
|
||||||
|
mProcessesToGc.remove(rec);
|
||||||
|
addProcessToGcListLocked(rec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scheduleAppGcsLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Config.LOGD) {
|
} else if (Config.LOGD) {
|
||||||
@@ -5112,7 +5136,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
app.instrumentationArguments, app.instrumentationWatcher, testMode,
|
app.instrumentationArguments, app.instrumentationWatcher, testMode,
|
||||||
isRestrictedBackupMode, mConfiguration, getCommonServicesLocked());
|
isRestrictedBackupMode, mConfiguration, getCommonServicesLocked());
|
||||||
updateLRUListLocked(app, false);
|
updateLRUListLocked(app, false);
|
||||||
app.lastRequestedGc = SystemClock.uptimeMillis();
|
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// todo: Yikes! What should we do? For now we will try to
|
// todo: Yikes! What should we do? For now we will try to
|
||||||
// start another process, but that could easily get us in
|
// start another process, but that could easily get us in
|
||||||
@@ -8795,6 +8819,24 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
"OnHold Norm", "OnHold PERS", false);
|
"OnHold Norm", "OnHold PERS", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mProcessesToGc.size() > 0) {
|
||||||
|
if (needSep) pw.println(" ");
|
||||||
|
needSep = true;
|
||||||
|
pw.println(" Processes that are waiting to GC:");
|
||||||
|
long now = SystemClock.uptimeMillis();
|
||||||
|
for (int i=0; i<mProcessesToGc.size(); i++) {
|
||||||
|
ProcessRecord proc = mProcessesToGc.get(i);
|
||||||
|
pw.print(" Process "); pw.println(proc);
|
||||||
|
pw.print(" lowMem="); pw.print(proc.reportLowMemory);
|
||||||
|
pw.print(", last gced=");
|
||||||
|
pw.print(now-proc.lastRequestedGc);
|
||||||
|
pw.print(" ms ago, last lowMwm=");
|
||||||
|
pw.print(now-proc.lastLowMemory);
|
||||||
|
pw.println(" ms ago");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mProcessCrashTimes.getMap().size() > 0) {
|
if (mProcessCrashTimes.getMap().size() > 0) {
|
||||||
if (needSep) pw.println(" ");
|
if (needSep) pw.println(" ");
|
||||||
needSep = true;
|
needSep = true;
|
||||||
@@ -9907,6 +9949,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final void scheduleServiceRestartLocked(ServiceRecord r) {
|
private final void scheduleServiceRestartLocked(ServiceRecord r) {
|
||||||
|
final long now = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
r.totalRestartCount++;
|
r.totalRestartCount++;
|
||||||
if (r.restartDelay == 0) {
|
if (r.restartDelay == 0) {
|
||||||
r.restartCount++;
|
r.restartCount++;
|
||||||
@@ -9917,19 +9961,41 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
// the beginning, so we don't infinitely increase the duration
|
// the beginning, so we don't infinitely increase the duration
|
||||||
// on a service that just occasionally gets killed (which is
|
// on a service that just occasionally gets killed (which is
|
||||||
// a normal case, due to process being killed to reclaim memory).
|
// a normal case, due to process being killed to reclaim memory).
|
||||||
long now = SystemClock.uptimeMillis();
|
if (now > (r.restartTime+SERVICE_RESET_RUN_DURATION)) {
|
||||||
if (now > (r.restartTime+(SERVICE_RESTART_DURATION*2*2*2))) {
|
|
||||||
r.restartCount = 1;
|
r.restartCount = 1;
|
||||||
r.restartDelay = SERVICE_RESTART_DURATION;
|
r.restartDelay = SERVICE_RESTART_DURATION;
|
||||||
} else {
|
} else {
|
||||||
r.restartDelay *= 2;
|
r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.nextRestartTime = now + r.restartDelay;
|
||||||
|
|
||||||
|
// Make sure that we don't end up restarting a bunch of services
|
||||||
|
// all at the same time.
|
||||||
|
boolean repeat;
|
||||||
|
do {
|
||||||
|
repeat = false;
|
||||||
|
for (int i=mRestartingServices.size()-1; i>=0; i--) {
|
||||||
|
ServiceRecord r2 = mRestartingServices.get(i);
|
||||||
|
if (r2 != r && r.nextRestartTime
|
||||||
|
>= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
|
||||||
|
&& r.nextRestartTime
|
||||||
|
< (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
|
||||||
|
r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
|
||||||
|
r.restartDelay = r.nextRestartTime - now;
|
||||||
|
repeat = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (repeat);
|
||||||
|
|
||||||
if (!mRestartingServices.contains(r)) {
|
if (!mRestartingServices.contains(r)) {
|
||||||
mRestartingServices.add(r);
|
mRestartingServices.add(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
mHandler.removeCallbacks(r.restarter);
|
mHandler.removeCallbacks(r.restarter);
|
||||||
mHandler.postDelayed(r.restarter, r.restartDelay);
|
mHandler.postAtTime(r.restarter, r.nextRestartTime);
|
||||||
r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
|
r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
|
||||||
Log.w(TAG, "Scheduling restart of crashed service "
|
Log.w(TAG, "Scheduling restart of crashed service "
|
||||||
+ r.shortName + " in " + r.restartDelay + "ms");
|
+ r.shortName + " in " + r.restartDelay + "ms");
|
||||||
@@ -12304,15 +12370,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
if (app == TOP_APP) {
|
if (app == TOP_APP) {
|
||||||
// The last app on the list is the foreground app.
|
// The last app on the list is the foreground app.
|
||||||
adj = FOREGROUND_APP_ADJ;
|
adj = FOREGROUND_APP_ADJ;
|
||||||
app.adjType = "top";
|
app.adjType = "top-activity";
|
||||||
} 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 = FOREGROUND_APP_ADJ;
|
adj = FOREGROUND_APP_ADJ;
|
||||||
app.adjType = "instr";
|
app.adjType = "instrumentation";
|
||||||
} else if (app.persistentActivities > 0) {
|
} else if (app.persistentActivities > 0) {
|
||||||
// Special persistent activities... shouldn't be used these days.
|
// Special persistent activities... shouldn't be used these days.
|
||||||
adj = FOREGROUND_APP_ADJ;
|
adj = FOREGROUND_APP_ADJ;
|
||||||
app.adjType = "pers";
|
app.adjType = "persistent";
|
||||||
} else if (app.curReceiver != null ||
|
} else if (app.curReceiver != null ||
|
||||||
(mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
|
(mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
|
||||||
// An app that is currently receiving a broadcast also
|
// An app that is currently receiving a broadcast also
|
||||||
@@ -12341,6 +12407,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
} else if ((N=app.activities.size()) != 0) {
|
} else if ((N=app.activities.size()) != 0) {
|
||||||
// This app is in the background with paused activities.
|
// This app is in the background with paused activities.
|
||||||
adj = hiddenAdj;
|
adj = hiddenAdj;
|
||||||
|
app.adjType = "bg-activities";
|
||||||
for (int j=0; j<N; j++) {
|
for (int j=0; j<N; j++) {
|
||||||
if (((HistoryRecord)app.activities.get(j)).visible) {
|
if (((HistoryRecord)app.activities.get(j)).visible) {
|
||||||
// This app has a visible activity!
|
// This app has a visible activity!
|
||||||
@@ -12380,7 +12447,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
// its services we may bump it up from there.
|
// its services we may bump it up from there.
|
||||||
if (adj > hiddenAdj) {
|
if (adj > hiddenAdj) {
|
||||||
adj = hiddenAdj;
|
adj = hiddenAdj;
|
||||||
app.adjType = "services";
|
app.adjType = "bg-services";
|
||||||
}
|
}
|
||||||
final long now = SystemClock.uptimeMillis();
|
final long now = SystemClock.uptimeMillis();
|
||||||
// This process is more important if the top activity is
|
// This process is more important if the top activity is
|
||||||
@@ -12522,8 +12589,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
try {
|
try {
|
||||||
app.lastRequestedGc = SystemClock.uptimeMillis();
|
app.lastRequestedGc = SystemClock.uptimeMillis();
|
||||||
if (app.thread != null) {
|
if (app.thread != null) {
|
||||||
|
if (app.reportLowMemory) {
|
||||||
|
app.reportLowMemory = false;
|
||||||
|
app.thread.scheduleLowMemory();
|
||||||
|
} else {
|
||||||
app.thread.processInBackground();
|
app.thread.processInBackground();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// whatever.
|
// whatever.
|
||||||
}
|
}
|
||||||
@@ -12551,15 +12623,25 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
if (canGcNow()) {
|
if (canGcNow()) {
|
||||||
while (mProcessesToGc.size() > 0) {
|
while (mProcessesToGc.size() > 0) {
|
||||||
ProcessRecord proc = mProcessesToGc.remove(0);
|
ProcessRecord proc = mProcessesToGc.remove(0);
|
||||||
if (proc.curRawAdj > VISIBLE_APP_ADJ) {
|
if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
|
||||||
|
if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
|
||||||
|
<= SystemClock.uptimeMillis()) {
|
||||||
// To avoid spamming the system, we will GC processes one
|
// To avoid spamming the system, we will GC processes one
|
||||||
// at a time, waiting a few seconds between each.
|
// at a time, waiting a few seconds between each.
|
||||||
performAppGcLocked(proc);
|
performAppGcLocked(proc);
|
||||||
scheduleAppGcsLocked();
|
scheduleAppGcsLocked();
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
// It hasn't been long enough since we last GCed this
|
||||||
|
// process... put it in the list to wait for its time.
|
||||||
|
addProcessToGcListLocked(proc);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduleAppGcsLocked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12579,8 +12661,39 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
*/
|
*/
|
||||||
final void scheduleAppGcsLocked() {
|
final void scheduleAppGcsLocked() {
|
||||||
mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
|
mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
|
||||||
|
|
||||||
|
if (mProcessesToGc.size() > 0) {
|
||||||
|
// Schedule a GC for the time to the next process.
|
||||||
|
ProcessRecord proc = mProcessesToGc.get(0);
|
||||||
Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
|
Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
|
||||||
mHandler.sendMessageDelayed(msg, GC_TIMEOUT);
|
|
||||||
|
long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
|
||||||
|
long now = SystemClock.uptimeMillis();
|
||||||
|
if (when < (now+GC_TIMEOUT)) {
|
||||||
|
when = now + GC_TIMEOUT;
|
||||||
|
}
|
||||||
|
mHandler.sendMessageAtTime(msg, when);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a process to the array of processes waiting to be GCed. Keeps the
|
||||||
|
* list in sorted order by the last GC time. The process can't already be
|
||||||
|
* on the list.
|
||||||
|
*/
|
||||||
|
final void addProcessToGcListLocked(ProcessRecord proc) {
|
||||||
|
boolean added = false;
|
||||||
|
for (int i=mProcessesToGc.size()-1; i>=0; i--) {
|
||||||
|
if (mProcessesToGc.get(i).lastRequestedGc <
|
||||||
|
proc.lastRequestedGc) {
|
||||||
|
added = true;
|
||||||
|
mProcessesToGc.add(i+1, proc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!added) {
|
||||||
|
mProcessesToGc.add(0, proc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12590,11 +12703,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
*/
|
*/
|
||||||
final void scheduleAppGcLocked(ProcessRecord app) {
|
final void scheduleAppGcLocked(ProcessRecord app) {
|
||||||
long now = SystemClock.uptimeMillis();
|
long now = SystemClock.uptimeMillis();
|
||||||
if ((app.lastRequestedGc+5000) > now) {
|
if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mProcessesToGc.contains(app)) {
|
if (!mProcessesToGc.contains(app)) {
|
||||||
mProcessesToGc.add(app);
|
addProcessToGcListLocked(app);
|
||||||
scheduleAppGcsLocked();
|
scheduleAppGcsLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ class ProcessRecord implements Watchdog.PssRequestor {
|
|||||||
ComponentName instrumentationResultClass;// copy of instrumentationClass
|
ComponentName instrumentationResultClass;// copy of instrumentationClass
|
||||||
BroadcastRecord curReceiver;// receiver currently running in the app
|
BroadcastRecord curReceiver;// receiver currently running in the app
|
||||||
long lastRequestedGc; // When we last asked the app to do a gc
|
long lastRequestedGc; // When we last asked the app to do a gc
|
||||||
|
long lastLowMemory; // When we last told the app that memory is low
|
||||||
|
boolean reportLowMemory; // Set to true when waiting to report low mem
|
||||||
int lastPss; // Last pss size reported by app.
|
int lastPss; // Last pss size reported by app.
|
||||||
String adjType; // Debugging: primary thing impacting oom_adj.
|
String adjType; // Debugging: primary thing impacting oom_adj.
|
||||||
Object adjSource; // Debugging: option dependent object.
|
Object adjSource; // Debugging: option dependent object.
|
||||||
|
|||||||
@@ -88,22 +88,23 @@ class ServiceRecord extends Binder {
|
|||||||
if (permission != null) {
|
if (permission != null) {
|
||||||
pw.print(prefix); pw.print("permission="); pw.println(permission);
|
pw.print(prefix); pw.print("permission="); pw.println(permission);
|
||||||
}
|
}
|
||||||
|
long now = SystemClock.uptimeMillis();
|
||||||
pw.print(prefix); pw.print("baseDir="); pw.print(baseDir);
|
pw.print(prefix); pw.print("baseDir="); pw.print(baseDir);
|
||||||
if (!resDir.equals(baseDir)) pw.print(" resDir="); pw.print(resDir);
|
if (!resDir.equals(baseDir)) pw.print(" resDir="); pw.print(resDir);
|
||||||
pw.print(" dataDir="); pw.println(dataDir);
|
pw.print(" dataDir="); pw.println(dataDir);
|
||||||
pw.print(prefix); pw.print("app="); pw.println(app);
|
pw.print(prefix); pw.print("app="); pw.println(app);
|
||||||
pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
|
pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
|
||||||
pw.print(" lastActivity="); pw.println(lastActivity);
|
pw.print(" lastActivity="); pw.println(lastActivity-now);
|
||||||
pw.print(prefix); pw.print("startRequested="); pw.print(startRequested);
|
pw.print(prefix); pw.print("startRequested="); pw.print(startRequested);
|
||||||
pw.print(" startId="); pw.print(lastStartId);
|
pw.print(" startId="); pw.print(lastStartId);
|
||||||
pw.print(" executeNesting="); pw.print(executeNesting);
|
pw.print(" executeNesting="); pw.print(executeNesting);
|
||||||
pw.print(" executingStart="); pw.print(executingStart);
|
pw.print(" executingStart="); pw.print(executingStart-now);
|
||||||
pw.print(" crashCount="); pw.println(crashCount);
|
pw.print(" crashCount="); pw.println(crashCount);
|
||||||
pw.print(prefix); pw.print("totalRestartCount="); pw.print(totalRestartCount);
|
pw.print(prefix); pw.print("totalRestartCount="); pw.print(totalRestartCount);
|
||||||
pw.print(" restartCount="); pw.print(restartCount);
|
pw.print(" restartCount="); pw.print(restartCount);
|
||||||
pw.print(" restartDelay="); pw.print(restartDelay);
|
pw.print(" restartDelay="); pw.print(restartDelay);
|
||||||
pw.print(" restartTime="); pw.print(restartTime);
|
pw.print(" restartTime="); pw.print(restartTime-now);
|
||||||
pw.print(" nextRestartTime="); pw.println(nextRestartTime);
|
pw.print(" nextRestartTime="); pw.println(nextRestartTime-now);
|
||||||
if (bindings.size() > 0) {
|
if (bindings.size() > 0) {
|
||||||
Iterator<IntentBindRecord> it = bindings.values().iterator();
|
Iterator<IntentBindRecord> it = bindings.values().iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user