Merge "Hopefully fix issue #2662536: Why is launcher being killed?" into froyo
This commit is contained in:
committed by
Android (Google) Code Review
commit
6d00151c51
@ -747,6 +747,24 @@ public class Process {
|
|||||||
*/
|
*/
|
||||||
public static final native void sendSignal(int pid, int signal);
|
public static final native void sendSignal(int pid, int signal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* Private impl for avoiding a log message... DO NOT USE without doing
|
||||||
|
* your own log, or the Android Illuminati will find you some night and
|
||||||
|
* beat you up.
|
||||||
|
*/
|
||||||
|
public static final void killProcessQuiet(int pid) {
|
||||||
|
sendSignalQuiet(pid, SIGNAL_KILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
* Private impl for avoiding a log message... DO NOT USE without doing
|
||||||
|
* your own log, or the Android Illuminati will find you some night and
|
||||||
|
* beat you up.
|
||||||
|
*/
|
||||||
|
public static final native void sendSignalQuiet(int pid, int signal);
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final native long getFreeMemory();
|
public static final native long getFreeMemory();
|
||||||
|
|
||||||
|
@ -311,8 +311,8 @@ jboolean android_os_Process_setOomAdj(JNIEnv* env, jobject clazz,
|
|||||||
sprintf(text, "%d", adj);
|
sprintf(text, "%d", adj);
|
||||||
write(fd, text, strlen(text));
|
write(fd, text, strlen(text));
|
||||||
close(fd);
|
close(fd);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
@ -797,6 +797,13 @@ void android_os_Process_sendSignal(JNIEnv* env, jobject clazz, jint pid, jint si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void android_os_Process_sendSignalQuiet(JNIEnv* env, jobject clazz, jint pid, jint sig)
|
||||||
|
{
|
||||||
|
if (pid > 0) {
|
||||||
|
kill(pid, sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static jlong android_os_Process_getElapsedCpuTime(JNIEnv* env, jobject clazz)
|
static jlong android_os_Process_getElapsedCpuTime(JNIEnv* env, jobject clazz)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
@ -854,6 +861,7 @@ static const JNINativeMethod methods[] = {
|
|||||||
{"setUid", "(I)I", (void*)android_os_Process_setUid},
|
{"setUid", "(I)I", (void*)android_os_Process_setUid},
|
||||||
{"setGid", "(I)I", (void*)android_os_Process_setGid},
|
{"setGid", "(I)I", (void*)android_os_Process_setGid},
|
||||||
{"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
|
{"sendSignal", "(II)V", (void*)android_os_Process_sendSignal},
|
||||||
|
{"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet},
|
||||||
{"supportsProcesses", "()Z", (void*)android_os_Process_supportsProcesses},
|
{"supportsProcesses", "()Z", (void*)android_os_Process_supportsProcesses},
|
||||||
{"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
|
{"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory},
|
||||||
{"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines},
|
{"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines},
|
||||||
|
@ -321,12 +321,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
static final int MAX_HIDDEN_APPS = 15;
|
static final int MAX_HIDDEN_APPS = 15;
|
||||||
|
|
||||||
// We put empty content processes after any hidden processes that have
|
// We put empty content processes after any hidden processes that have
|
||||||
// been idle for less than 30 seconds.
|
// been idle for less than 15 seconds.
|
||||||
static final long CONTENT_APP_IDLE_OFFSET = 30*1000;
|
static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
|
||||||
|
|
||||||
// We put empty content processes after any hidden processes that have
|
// We put empty content processes after any hidden processes that have
|
||||||
// been idle for less than 60 seconds.
|
// been idle for less than 120 seconds.
|
||||||
static final long EMPTY_APP_IDLE_OFFSET = 60*1000;
|
static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// These values are set in system/rootdir/init.rc on startup.
|
// These values are set in system/rootdir/init.rc on startup.
|
||||||
@ -879,6 +879,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
*/
|
*/
|
||||||
int mAdjSeq = 0;
|
int mAdjSeq = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current sequence id for process LRU updating.
|
||||||
|
*/
|
||||||
|
int mLruSeq = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
|
* Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
|
||||||
* is set, indicating the user wants processes started in such a way
|
* is set, indicating the user wants processes started in such a way
|
||||||
@ -1588,8 +1593,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void updateLruProcessLocked(ProcessRecord app,
|
private final void updateLruProcessInternalLocked(ProcessRecord app,
|
||||||
boolean oomAdj, boolean updateActivityTime) {
|
boolean oomAdj, boolean updateActivityTime, int bestPos) {
|
||||||
// put it on the LRU to keep track of when it should be exited.
|
// put it on the LRU to keep track of when it should be exited.
|
||||||
int lrui = mLruProcesses.indexOf(app);
|
int lrui = mLruProcesses.indexOf(app);
|
||||||
if (lrui >= 0) mLruProcesses.remove(lrui);
|
if (lrui >= 0) mLruProcesses.remove(lrui);
|
||||||
@ -1597,6 +1602,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
int i = mLruProcesses.size()-1;
|
int i = mLruProcesses.size()-1;
|
||||||
int skipTop = 0;
|
int skipTop = 0;
|
||||||
|
|
||||||
|
app.lruSeq = mLruSeq;
|
||||||
|
|
||||||
// compute the new weight for this process.
|
// compute the new weight for this process.
|
||||||
if (updateActivityTime) {
|
if (updateActivityTime) {
|
||||||
app.lastActivityTime = SystemClock.uptimeMillis();
|
app.lastActivityTime = SystemClock.uptimeMillis();
|
||||||
@ -1619,6 +1626,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
// Also don't let it kick out the first few "real" hidden processes.
|
// Also don't let it kick out the first few "real" hidden processes.
|
||||||
skipTop = MIN_HIDDEN_APPS;
|
skipTop = MIN_HIDDEN_APPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i >= 0) {
|
while (i >= 0) {
|
||||||
ProcessRecord p = mLruProcesses.get(i);
|
ProcessRecord p = mLruProcesses.get(i);
|
||||||
// If this app shouldn't be in front of the first N background
|
// If this app shouldn't be in front of the first N background
|
||||||
@ -1626,7 +1634,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
|
if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
|
||||||
skipTop--;
|
skipTop--;
|
||||||
}
|
}
|
||||||
if (p.lruWeight <= app.lruWeight){
|
if (p.lruWeight <= app.lruWeight || i < bestPos) {
|
||||||
mLruProcesses.add(i+1, app);
|
mLruProcesses.add(i+1, app);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1636,12 +1644,39 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
mLruProcesses.add(0, app);
|
mLruProcesses.add(0, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the app is currently using a content provider or service,
|
||||||
|
// bump those processes as well.
|
||||||
|
if (app.connections.size() > 0) {
|
||||||
|
for (ConnectionRecord cr : app.connections) {
|
||||||
|
if (cr.binding != null && cr.binding.service != null
|
||||||
|
&& cr.binding.service.app != null
|
||||||
|
&& cr.binding.service.app.lruSeq != mLruSeq) {
|
||||||
|
updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
|
||||||
|
updateActivityTime, i+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (app.conProviders.size() > 0) {
|
||||||
|
for (ContentProviderRecord cpr : app.conProviders.keySet()) {
|
||||||
|
if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
|
||||||
|
updateLruProcessInternalLocked(cpr.app, oomAdj,
|
||||||
|
updateActivityTime, i+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Slog.i(TAG, "Putting proc to front: " + app.processName);
|
//Slog.i(TAG, "Putting proc to front: " + app.processName);
|
||||||
if (oomAdj) {
|
if (oomAdj) {
|
||||||
updateOomAdjLocked();
|
updateOomAdjLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final void updateLruProcessLocked(ProcessRecord app,
|
||||||
|
boolean oomAdj, boolean updateActivityTime) {
|
||||||
|
mLruSeq++;
|
||||||
|
updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private final boolean updateLRUListLocked(HistoryRecord r) {
|
private final boolean updateLRUListLocked(HistoryRecord r) {
|
||||||
final boolean hadit = mLRUActivities.remove(r);
|
final boolean hadit = mLRUActivities.remove(r);
|
||||||
mLRUActivities.add(r);
|
mLRUActivities.add(r);
|
||||||
@ -4677,8 +4712,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
// Clean up already done if the process has been re-started.
|
// Clean up already done if the process has been re-started.
|
||||||
if (app.pid == pid && app.thread != null &&
|
if (app.pid == pid && app.thread != null &&
|
||||||
app.thread.asBinder() == thread.asBinder()) {
|
app.thread.asBinder() == thread.asBinder()) {
|
||||||
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
|
if (!app.killedBackground) {
|
||||||
+ ") has died.");
|
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.pid, app.processName);
|
||||||
if (localLOGV) Slog.v(
|
if (localLOGV) Slog.v(
|
||||||
TAG, "Dying app: " + app + ", pid: " + pid
|
TAG, "Dying app: " + app + ", pid: " + pid
|
||||||
@ -7826,6 +7863,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cpr.app != null) {
|
if (cpr.app != null) {
|
||||||
|
if (r.setAdj >= VISIBLE_APP_ADJ) {
|
||||||
|
// If this is a visible app accessing the provider,
|
||||||
|
// 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.app, false, true);
|
||||||
|
}
|
||||||
updateOomAdjLocked(cpr.app);
|
updateOomAdjLocked(cpr.app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8492,12 +8536,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int adj = proc.setAdj;
|
int adj = proc.setAdj;
|
||||||
if (adj >= worstType) {
|
if (adj >= worstType && !proc.killedBackground) {
|
||||||
Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
|
Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
|
||||||
EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
|
EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
|
||||||
proc.processName, adj, reason);
|
proc.processName, adj, reason);
|
||||||
killed = true;
|
killed = true;
|
||||||
Process.killProcess(pids[i]);
|
proc.killedBackground = true;
|
||||||
|
Process.killProcessQuiet(pids[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9829,6 +9874,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
+ " mFactoryTest=" + mFactoryTest);
|
+ " mFactoryTest=" + mFactoryTest);
|
||||||
pw.println(" mGoingToSleep=" + mGoingToSleep);
|
pw.println(" mGoingToSleep=" + mGoingToSleep);
|
||||||
pw.println(" mLaunchingActivity=" + mLaunchingActivity);
|
pw.println(" mLaunchingActivity=" + mLaunchingActivity);
|
||||||
|
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -14292,13 +14338,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
|
|||||||
if (!app.killedBackground) {
|
if (!app.killedBackground) {
|
||||||
numHidden++;
|
numHidden++;
|
||||||
if (numHidden > MAX_HIDDEN_APPS) {
|
if (numHidden > MAX_HIDDEN_APPS) {
|
||||||
Slog.i(TAG, "Kill " + app.processName
|
Slog.i(TAG, "No longer want " + app.processName
|
||||||
+ " (pid " + app.pid + "): hidden #" + numHidden
|
+ " (pid " + app.pid + "): hidden #" + numHidden);
|
||||||
+ " beyond limit " + MAX_HIDDEN_APPS);
|
|
||||||
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
|
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
|
||||||
app.processName, app.setAdj, "too many background");
|
app.processName, app.setAdj, "too many background");
|
||||||
app.killedBackground = true;
|
app.killedBackground = true;
|
||||||
Process.killProcess(app.pid);
|
Process.killProcessQuiet(app.pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,8 @@ class ProcessRecord implements Watchdog.PssRequestor {
|
|||||||
boolean bad; // True if disabled in the bad process list
|
boolean bad; // True if disabled in the bad process list
|
||||||
boolean killedBackground; // True when proc has been killed due to too many bg
|
boolean killedBackground; // True when proc has been killed due to too many bg
|
||||||
IBinder forcingToForeground;// Token that is forcing this process to be foreground
|
IBinder forcingToForeground;// Token that is forcing this process to be foreground
|
||||||
int adjSeq; // Sequence id for identifying repeated trav
|
int adjSeq; // Sequence id for identifying oom_adj assignment cycles
|
||||||
|
int lruSeq; // Sequence id for identifying LRU update cycles
|
||||||
ComponentName instrumentationClass;// class installed to instrument app
|
ComponentName instrumentationClass;// class installed to instrument app
|
||||||
ApplicationInfo instrumentationInfo; // the application being instrumented
|
ApplicationInfo instrumentationInfo; // the application being instrumented
|
||||||
String instrumentationProfileFile; // where to save profiling
|
String instrumentationProfileFile; // where to save profiling
|
||||||
@ -175,6 +176,8 @@ class ProcessRecord implements Watchdog.PssRequestor {
|
|||||||
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
|
pw.print(prefix); pw.print("persistent="); pw.print(persistent);
|
||||||
pw.print(" removed="); pw.print(removed);
|
pw.print(" removed="); pw.print(removed);
|
||||||
pw.print(" persistentActivities="); pw.println(persistentActivities);
|
pw.print(" persistentActivities="); pw.println(persistentActivities);
|
||||||
|
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
|
||||||
|
pw.print(" lruSeq="); pw.println(lruSeq);
|
||||||
if (killedBackground) {
|
if (killedBackground) {
|
||||||
pw.print(prefix); pw.print("killedBackground="); pw.println(killedBackground);
|
pw.print(prefix); pw.print("killedBackground="); pw.println(killedBackground);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user