Loading core/java/android/os/Process.java +18 −0 Original line number Diff line number Diff line Loading @@ -747,6 +747,24 @@ public class Process { */ 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 */ public static final native long getFreeMemory(); Loading core/jni/android_util_Process.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -311,8 +311,8 @@ jboolean android_os_Process_setOomAdj(JNIEnv* env, jobject clazz, sprintf(text, "%d", adj); write(fd, text, strlen(text)); close(fd); return true; } return true; } #endif return false; Loading Loading @@ -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) { struct timespec ts; Loading Loading @@ -854,6 +861,7 @@ static const JNINativeMethod methods[] = { {"setUid", "(I)I", (void*)android_os_Process_setUid}, {"setGid", "(I)I", (void*)android_os_Process_setGid}, {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal}, {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet}, {"supportsProcesses", "()Z", (void*)android_os_Process_supportsProcesses}, {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory}, {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines}, Loading services/java/com/android/server/am/ActivityManagerService.java +60 −15 Original line number Diff line number Diff line Loading @@ -321,12 +321,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen static final int MAX_HIDDEN_APPS = 15; // We put empty content processes after any hidden processes that have // been idle for less than 30 seconds. static final long CONTENT_APP_IDLE_OFFSET = 30*1000; // been idle for less than 15 seconds. static final long CONTENT_APP_IDLE_OFFSET = 15*1000; // We put empty content processes after any hidden processes that have // been idle for less than 60 seconds. static final long EMPTY_APP_IDLE_OFFSET = 60*1000; // been idle for less than 120 seconds. static final long EMPTY_APP_IDLE_OFFSET = 120*1000; static { // These values are set in system/rootdir/init.rc on startup. Loading Loading @@ -879,6 +879,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen */ int mAdjSeq = 0; /** * Current sequence id for process LRU updating. */ int mLruSeq = 0; /** * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar * is set, indicating the user wants processes started in such a way Loading Loading @@ -1588,8 +1593,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } private final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime) { private final void updateLruProcessInternalLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime, 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); Loading @@ -1597,6 +1602,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int i = mLruProcesses.size()-1; int skipTop = 0; app.lruSeq = mLruSeq; // compute the new weight for this process. if (updateActivityTime) { app.lastActivityTime = SystemClock.uptimeMillis(); Loading @@ -1619,6 +1626,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Also don't let it kick out the first few "real" hidden processes. skipTop = MIN_HIDDEN_APPS; } while (i >= 0) { ProcessRecord p = mLruProcesses.get(i); // If this app shouldn't be in front of the first N background Loading @@ -1626,7 +1634,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) { skipTop--; } if (p.lruWeight <= app.lruWeight){ if (p.lruWeight <= app.lruWeight || i < bestPos) { mLruProcesses.add(i+1, app); break; } Loading @@ -1636,12 +1644,39 @@ public final class ActivityManagerService extends ActivityManagerNative implemen 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); if (oomAdj) { updateOomAdjLocked(); } } private final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime) { mLruSeq++; updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); } private final boolean updateLRUListLocked(HistoryRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); Loading Loading @@ -4677,8 +4712,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Clean up already done if the process has been re-started. if (app.pid == pid && app.thread != null && app.thread.asBinder() == thread.asBinder()) { if (!app.killedBackground) { Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died."); } EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); if (localLOGV) Slog.v( TAG, "Dying app: " + app + ", pid: " + pid Loading Loading @@ -7826,6 +7863,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } 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); } Loading Loading @@ -8492,12 +8536,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen continue; } int adj = proc.setAdj; if (adj >= worstType) { if (adj >= worstType && !proc.killedBackground) { Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); killed = true; Process.killProcess(pids[i]); proc.killedBackground = true; Process.killProcessQuiet(pids[i]); } } } Loading Loading @@ -9829,6 +9874,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen + " mFactoryTest=" + mFactoryTest); pw.println(" mGoingToSleep=" + mGoingToSleep); pw.println(" mLaunchingActivity=" + mLaunchingActivity); pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); } return true; Loading Loading @@ -14292,13 +14338,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (!app.killedBackground) { numHidden++; if (numHidden > MAX_HIDDEN_APPS) { Slog.i(TAG, "Kill " + app.processName + " (pid " + app.pid + "): hidden #" + numHidden + " beyond limit " + MAX_HIDDEN_APPS); Slog.i(TAG, "No longer want " + app.processName + " (pid " + app.pid + "): hidden #" + numHidden); EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, app.processName, app.setAdj, "too many background"); app.killedBackground = true; Process.killProcess(app.pid); Process.killProcessQuiet(app.pid); } } } services/java/com/android/server/am/ProcessRecord.java +4 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ class ProcessRecord implements Watchdog.PssRequestor { boolean bad; // True if disabled in the bad process list boolean killedBackground; // True when proc has been killed due to too many bg 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 ApplicationInfo instrumentationInfo; // the application being instrumented String instrumentationProfileFile; // where to save profiling Loading Loading @@ -175,6 +176,8 @@ class ProcessRecord implements Watchdog.PssRequestor { pw.print(prefix); pw.print("persistent="); pw.print(persistent); pw.print(" removed="); pw.print(removed); pw.print(" persistentActivities="); pw.println(persistentActivities); pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); pw.print(" lruSeq="); pw.println(lruSeq); if (killedBackground) { pw.print(prefix); pw.print("killedBackground="); pw.println(killedBackground); } Loading Loading
core/java/android/os/Process.java +18 −0 Original line number Diff line number Diff line Loading @@ -747,6 +747,24 @@ public class Process { */ 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 */ public static final native long getFreeMemory(); Loading
core/jni/android_util_Process.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -311,8 +311,8 @@ jboolean android_os_Process_setOomAdj(JNIEnv* env, jobject clazz, sprintf(text, "%d", adj); write(fd, text, strlen(text)); close(fd); return true; } return true; } #endif return false; Loading Loading @@ -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) { struct timespec ts; Loading Loading @@ -854,6 +861,7 @@ static const JNINativeMethod methods[] = { {"setUid", "(I)I", (void*)android_os_Process_setUid}, {"setGid", "(I)I", (void*)android_os_Process_setGid}, {"sendSignal", "(II)V", (void*)android_os_Process_sendSignal}, {"sendSignalQuiet", "(II)V", (void*)android_os_Process_sendSignalQuiet}, {"supportsProcesses", "()Z", (void*)android_os_Process_supportsProcesses}, {"getFreeMemory", "()J", (void*)android_os_Process_getFreeMemory}, {"readProcLines", "(Ljava/lang/String;[Ljava/lang/String;[J)V", (void*)android_os_Process_readProcLines}, Loading
services/java/com/android/server/am/ActivityManagerService.java +60 −15 Original line number Diff line number Diff line Loading @@ -321,12 +321,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen static final int MAX_HIDDEN_APPS = 15; // We put empty content processes after any hidden processes that have // been idle for less than 30 seconds. static final long CONTENT_APP_IDLE_OFFSET = 30*1000; // been idle for less than 15 seconds. static final long CONTENT_APP_IDLE_OFFSET = 15*1000; // We put empty content processes after any hidden processes that have // been idle for less than 60 seconds. static final long EMPTY_APP_IDLE_OFFSET = 60*1000; // been idle for less than 120 seconds. static final long EMPTY_APP_IDLE_OFFSET = 120*1000; static { // These values are set in system/rootdir/init.rc on startup. Loading Loading @@ -879,6 +879,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen */ int mAdjSeq = 0; /** * Current sequence id for process LRU updating. */ int mLruSeq = 0; /** * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar * is set, indicating the user wants processes started in such a way Loading Loading @@ -1588,8 +1593,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } private final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime) { private final void updateLruProcessInternalLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime, 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); Loading @@ -1597,6 +1602,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int i = mLruProcesses.size()-1; int skipTop = 0; app.lruSeq = mLruSeq; // compute the new weight for this process. if (updateActivityTime) { app.lastActivityTime = SystemClock.uptimeMillis(); Loading @@ -1619,6 +1626,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Also don't let it kick out the first few "real" hidden processes. skipTop = MIN_HIDDEN_APPS; } while (i >= 0) { ProcessRecord p = mLruProcesses.get(i); // If this app shouldn't be in front of the first N background Loading @@ -1626,7 +1634,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) { skipTop--; } if (p.lruWeight <= app.lruWeight){ if (p.lruWeight <= app.lruWeight || i < bestPos) { mLruProcesses.add(i+1, app); break; } Loading @@ -1636,12 +1644,39 @@ public final class ActivityManagerService extends ActivityManagerNative implemen 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); if (oomAdj) { updateOomAdjLocked(); } } private final void updateLruProcessLocked(ProcessRecord app, boolean oomAdj, boolean updateActivityTime) { mLruSeq++; updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); } private final boolean updateLRUListLocked(HistoryRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); Loading Loading @@ -4677,8 +4712,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // Clean up already done if the process has been re-started. if (app.pid == pid && app.thread != null && app.thread.asBinder() == thread.asBinder()) { if (!app.killedBackground) { Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died."); } EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); if (localLOGV) Slog.v( TAG, "Dying app: " + app + ", pid: " + pid Loading Loading @@ -7826,6 +7863,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } 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); } Loading Loading @@ -8492,12 +8536,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen continue; } int adj = proc.setAdj; if (adj >= worstType) { if (adj >= worstType && !proc.killedBackground) { Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); killed = true; Process.killProcess(pids[i]); proc.killedBackground = true; Process.killProcessQuiet(pids[i]); } } } Loading Loading @@ -9829,6 +9874,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen + " mFactoryTest=" + mFactoryTest); pw.println(" mGoingToSleep=" + mGoingToSleep); pw.println(" mLaunchingActivity=" + mLaunchingActivity); pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); } return true; Loading Loading @@ -14292,13 +14338,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (!app.killedBackground) { numHidden++; if (numHidden > MAX_HIDDEN_APPS) { Slog.i(TAG, "Kill " + app.processName + " (pid " + app.pid + "): hidden #" + numHidden + " beyond limit " + MAX_HIDDEN_APPS); Slog.i(TAG, "No longer want " + app.processName + " (pid " + app.pid + "): hidden #" + numHidden); EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, app.processName, app.setAdj, "too many background"); app.killedBackground = true; Process.killProcess(app.pid); Process.killProcessQuiet(app.pid); } } }
services/java/com/android/server/am/ProcessRecord.java +4 −1 Original line number Diff line number Diff line Loading @@ -66,7 +66,8 @@ class ProcessRecord implements Watchdog.PssRequestor { boolean bad; // True if disabled in the bad process list boolean killedBackground; // True when proc has been killed due to too many bg 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 ApplicationInfo instrumentationInfo; // the application being instrumented String instrumentationProfileFile; // where to save profiling Loading Loading @@ -175,6 +176,8 @@ class ProcessRecord implements Watchdog.PssRequestor { pw.print(prefix); pw.print("persistent="); pw.print(persistent); pw.print(" removed="); pw.print(removed); pw.print(" persistentActivities="); pw.println(persistentActivities); pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); pw.print(" lruSeq="); pw.println(lruSeq); if (killedBackground) { pw.print(prefix); pw.print("killedBackground="); pw.println(killedBackground); } Loading