Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +8 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_PROCESS_START_ASYNC = "process_start_async"; static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time"; static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration"; static final String KEY_USE_COMPACTION = "use_compaction"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading Loading @@ -99,6 +100,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final boolean DEFAULT_PROCESS_START_ASYNC = true; private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000; private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000; private static final boolean DEFAULT_USE_COMPACTION = false; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -218,6 +220,9 @@ final class ActivityManagerConstants extends ContentObserver { // this long. public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION; // Use compaction for background apps. public boolean USE_COMPACTION = DEFAULT_USE_COMPACTION; // Indicates whether the activity starts logging is enabled. // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED volatile boolean mFlagActivityStartsLoggingEnabled; Loading Loading @@ -375,6 +380,7 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_MEMORY_INFO_THROTTLE_TIME); TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION, DEFAULT_TOP_TO_FGS_GRACE_DURATION); USE_COMPACTION = mParser.getBoolean(KEY_USE_COMPACTION, DEFAULT_USE_COMPACTION); updateMaxCachedProcesses(); } Loading Loading @@ -465,6 +471,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(MEMORY_INFO_THROTTLE_TIME); pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("="); pw.println(TOP_TO_FGS_GRACE_DURATION); pw.print(" "); pw.print(KEY_USE_COMPACTION); pw.print("="); pw.println(USE_COMPACTION); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +117 −2 Original line number Diff line number Diff line Loading @@ -795,6 +795,11 @@ public class ActivityManagerService extends IActivityManager.Stub */ final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); /** * Processes to compact. */ final ArrayList<ProcessRecord> mPendingCompactionProcesses = new ArrayList<ProcessRecord>(); private boolean mBinderTransactionTrackingEnabled = false; /** Loading Loading @@ -1452,6 +1457,7 @@ public class ActivityManagerService extends IActivityManager.Stub final Handler mUiHandler; final ServiceThread mProcStartHandlerThread; final Handler mProcStartHandler; final ServiceThread mCompactionThread; final ActivityManagerConstants mConstants; Loading Loading @@ -1789,6 +1795,11 @@ public class ActivityManagerService extends IActivityManager.Stub } }; static final int COMPACT_PROCESS_SOME = 1; static final int COMPACT_PROCESS_FULL = 2; static final int COMPACT_PROCESS_MSG = 1; final Handler mCompactionHandler; static final int COLLECT_PSS_BG_MSG = 1; final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { Loading Loading @@ -2224,6 +2235,8 @@ public class ActivityManagerService extends IActivityManager.Stub ? new PendingIntentController(handlerThread.getLooper(), mUserController) : null; mProcStartHandlerThread = null; mProcStartHandler = null; mCompactionThread = null; mCompactionHandler = null; mHiddenApiBlacklist = null; mFactoryTest = FACTORY_TEST_OFF; } Loading Loading @@ -2252,6 +2265,88 @@ public class ActivityManagerService extends IActivityManager.Stub mProcStartHandlerThread.start(); mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper()); mCompactionThread = new ServiceThread("CompactionThread", THREAD_PRIORITY_FOREGROUND, true); mCompactionThread.start(); mCompactionHandler = new Handler(mCompactionThread.getLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case COMPACT_PROCESS_MSG: { long start = SystemClock.uptimeMillis(); ProcessRecord proc; int pid; String action; final String name; int pendingAction, lastCompactAction; long lastCompactTime; synchronized(ActivityManagerService.this) { proc = mPendingCompactionProcesses.remove(0); // don't compact if the process has returned to perceptible if (proc.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { return; } pid = proc.pid; name = proc.processName; pendingAction = proc.reqCompactAction; lastCompactAction = proc.lastCompactAction; lastCompactTime = proc.lastCompactTime; } if (pid == 0) { // not a real process, either one being launched or one being killed return; } // basic throttling if (pendingAction == COMPACT_PROCESS_SOME) { // if we're compacting some, then compact if >10s after last full // or >5s after last some if ((lastCompactAction == COMPACT_PROCESS_SOME && (start - lastCompactTime < 5000)) || (lastCompactAction == COMPACT_PROCESS_FULL && (start - lastCompactTime < 10000))) return; } else { // if we're compacting full, then compact if >10s after last full // or >.5s after last some if ((lastCompactAction == COMPACT_PROCESS_SOME && (start - lastCompactTime < 500)) || (lastCompactAction == COMPACT_PROCESS_FULL && (start - lastCompactTime < 10000))) return; } try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Compact " + ((pendingAction == COMPACT_PROCESS_SOME) ? "some" : "full") + ": " + name); long[] rssBefore = Process.getRss(pid); FileOutputStream fos = new FileOutputStream("/proc/" + pid + "/reclaim"); if (pendingAction == COMPACT_PROCESS_SOME) { action = "file"; } else { action = "all"; } fos.write(action.getBytes()); fos.close(); long[] rssAfter = Process.getRss(pid); long end = SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.AM_COMPACT, pid, name, action, rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3], rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], end-start); synchronized(ActivityManagerService.this) { proc.lastCompactTime = end; proc.lastCompactAction = pendingAction; } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } catch (Exception e) { // nothing to do, presumably the process died Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } } } }; mConstants = new ActivityManagerConstants(this, mHandler); mProcessList.init(this); Loading Loading @@ -2345,13 +2440,15 @@ public class ActivityManagerService extends IActivityManager.Stub Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); // bind background thread to little cores // bind background threads to little cores // this is expected to fail inside of framework tests because apps can't touch cpusets directly // make sure we've already adjusted system_server's internal view of itself first updateOomAdjLocked(); try { Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(), Process.THREAD_GROUP_BG_NONINTERACTIVE); Process.THREAD_GROUP_SYSTEM); Process.setThreadGroupAndCpuset(mCompactionThread.getThreadId(), Process.THREAD_GROUP_SYSTEM); } catch (Exception e) { Slog.w(TAG, "Setting background thread cpuset failed"); } Loading Loading @@ -16921,6 +17018,24 @@ public class ActivityManagerService extends IActivityManager.Stub int changes = 0; if (app.curAdj != app.setAdj) { // don't compact during bootup if (mConstants.USE_COMPACTION && mBooted) { // Perform a minor compaction when a perceptible app becomes the prev/home app // Perform a major compaction when any app enters cached // reminder: here, setAdj is previous state, curAdj is upcoming state if (app.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (app.curAdj == ProcessList.PREVIOUS_APP_ADJ || app.curAdj == ProcessList.HOME_APP_ADJ)) { app.reqCompactAction = COMPACT_PROCESS_SOME; mPendingCompactionProcesses.add(app); mCompactionHandler.sendEmptyMessage(COMPACT_PROCESS_MSG); } else if (app.setAdj < ProcessList.CACHED_APP_MIN_ADJ && app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ) { app.reqCompactAction = COMPACT_PROCESS_FULL; mPendingCompactionProcesses.add(app); mCompactionHandler.sendEmptyMessage(COMPACT_PROCESS_MSG); } } ProcessList.setOomAdj(app.pid, app.uid, app.curAdj); if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) { String msg = "Set " + app.pid + " " + app.processName + " adj " services/core/java/com/android/server/am/EventLogTags.logtags +4 −1 Original line number Diff line number Diff line Loading @@ -136,3 +136,6 @@ option java_package com.android.server.am # The task is being removed from its parent stack 30061 am_remove_task (Task ID|1|5), (Stack ID|1|5) # The task is being compacted 30063 am_compact (Pid|1|5),(Process Name|3),(Action|3),(BeforeRssTotal|2|2),(BeforeRssFile|2|2),(BeforeRssAnon|2|2),(BeforeRssSwap|2|2),(AfterRssTotal|2|2),(AfterRssFile|2|2),(AfterRssAnon|2|2),(AfterRssSwap|2|2),(Time|2|3) No newline at end of file services/core/java/com/android/server/am/ProcessRecord.java +5 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,9 @@ final class ProcessRecord implements WindowProcessListener { int curAdj; // Current OOM adjustment for this process int setAdj; // Last set OOM adjustment for this process int verifiedAdj; // The last adjustment that was verified as actually being set long lastCompactTime; // The last time that this process was compacted int reqCompactAction; // The most recent compaction action requested for this app. int lastCompactAction; // The most recent compaction action performed for this app. private int mCurSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class int trimMemoryLevel; // Last selected memory trimming level Loading Loading @@ -382,6 +385,8 @@ final class ProcessRecord implements WindowProcessListener { pw.print(" setRaw="); pw.print(setRawAdj); pw.print(" cur="); pw.print(curAdj); pw.print(" set="); pw.println(setAdj); pw.print(prefix); pw.print("lastCompactTime="); pw.print(lastCompactTime); pw.print(" lastCompactAction="); pw.print(lastCompactAction); pw.print(prefix); pw.print("mCurSchedGroup="); pw.print(mCurSchedGroup); pw.print(" setSchedGroup="); pw.print(setSchedGroup); pw.print(" systemNoUi="); pw.print(systemNoUi); Loading Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +8 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_PROCESS_START_ASYNC = "process_start_async"; static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time"; static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration"; static final String KEY_USE_COMPACTION = "use_compaction"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading Loading @@ -99,6 +100,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final boolean DEFAULT_PROCESS_START_ASYNC = true; private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000; private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000; private static final boolean DEFAULT_USE_COMPACTION = false; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -218,6 +220,9 @@ final class ActivityManagerConstants extends ContentObserver { // this long. public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION; // Use compaction for background apps. public boolean USE_COMPACTION = DEFAULT_USE_COMPACTION; // Indicates whether the activity starts logging is enabled. // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED volatile boolean mFlagActivityStartsLoggingEnabled; Loading Loading @@ -375,6 +380,7 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_MEMORY_INFO_THROTTLE_TIME); TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION, DEFAULT_TOP_TO_FGS_GRACE_DURATION); USE_COMPACTION = mParser.getBoolean(KEY_USE_COMPACTION, DEFAULT_USE_COMPACTION); updateMaxCachedProcesses(); } Loading Loading @@ -465,6 +471,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(MEMORY_INFO_THROTTLE_TIME); pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("="); pw.println(TOP_TO_FGS_GRACE_DURATION); pw.print(" "); pw.print(KEY_USE_COMPACTION); pw.print("="); pw.println(USE_COMPACTION); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +117 −2 Original line number Diff line number Diff line Loading @@ -795,6 +795,11 @@ public class ActivityManagerService extends IActivityManager.Stub */ final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); /** * Processes to compact. */ final ArrayList<ProcessRecord> mPendingCompactionProcesses = new ArrayList<ProcessRecord>(); private boolean mBinderTransactionTrackingEnabled = false; /** Loading Loading @@ -1452,6 +1457,7 @@ public class ActivityManagerService extends IActivityManager.Stub final Handler mUiHandler; final ServiceThread mProcStartHandlerThread; final Handler mProcStartHandler; final ServiceThread mCompactionThread; final ActivityManagerConstants mConstants; Loading Loading @@ -1789,6 +1795,11 @@ public class ActivityManagerService extends IActivityManager.Stub } }; static final int COMPACT_PROCESS_SOME = 1; static final int COMPACT_PROCESS_FULL = 2; static final int COMPACT_PROCESS_MSG = 1; final Handler mCompactionHandler; static final int COLLECT_PSS_BG_MSG = 1; final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { Loading Loading @@ -2224,6 +2235,8 @@ public class ActivityManagerService extends IActivityManager.Stub ? new PendingIntentController(handlerThread.getLooper(), mUserController) : null; mProcStartHandlerThread = null; mProcStartHandler = null; mCompactionThread = null; mCompactionHandler = null; mHiddenApiBlacklist = null; mFactoryTest = FACTORY_TEST_OFF; } Loading Loading @@ -2252,6 +2265,88 @@ public class ActivityManagerService extends IActivityManager.Stub mProcStartHandlerThread.start(); mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper()); mCompactionThread = new ServiceThread("CompactionThread", THREAD_PRIORITY_FOREGROUND, true); mCompactionThread.start(); mCompactionHandler = new Handler(mCompactionThread.getLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case COMPACT_PROCESS_MSG: { long start = SystemClock.uptimeMillis(); ProcessRecord proc; int pid; String action; final String name; int pendingAction, lastCompactAction; long lastCompactTime; synchronized(ActivityManagerService.this) { proc = mPendingCompactionProcesses.remove(0); // don't compact if the process has returned to perceptible if (proc.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { return; } pid = proc.pid; name = proc.processName; pendingAction = proc.reqCompactAction; lastCompactAction = proc.lastCompactAction; lastCompactTime = proc.lastCompactTime; } if (pid == 0) { // not a real process, either one being launched or one being killed return; } // basic throttling if (pendingAction == COMPACT_PROCESS_SOME) { // if we're compacting some, then compact if >10s after last full // or >5s after last some if ((lastCompactAction == COMPACT_PROCESS_SOME && (start - lastCompactTime < 5000)) || (lastCompactAction == COMPACT_PROCESS_FULL && (start - lastCompactTime < 10000))) return; } else { // if we're compacting full, then compact if >10s after last full // or >.5s after last some if ((lastCompactAction == COMPACT_PROCESS_SOME && (start - lastCompactTime < 500)) || (lastCompactAction == COMPACT_PROCESS_FULL && (start - lastCompactTime < 10000))) return; } try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Compact " + ((pendingAction == COMPACT_PROCESS_SOME) ? "some" : "full") + ": " + name); long[] rssBefore = Process.getRss(pid); FileOutputStream fos = new FileOutputStream("/proc/" + pid + "/reclaim"); if (pendingAction == COMPACT_PROCESS_SOME) { action = "file"; } else { action = "all"; } fos.write(action.getBytes()); fos.close(); long[] rssAfter = Process.getRss(pid); long end = SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.AM_COMPACT, pid, name, action, rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3], rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], end-start); synchronized(ActivityManagerService.this) { proc.lastCompactTime = end; proc.lastCompactAction = pendingAction; } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } catch (Exception e) { // nothing to do, presumably the process died Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } } } }; mConstants = new ActivityManagerConstants(this, mHandler); mProcessList.init(this); Loading Loading @@ -2345,13 +2440,15 @@ public class ActivityManagerService extends IActivityManager.Stub Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); // bind background thread to little cores // bind background threads to little cores // this is expected to fail inside of framework tests because apps can't touch cpusets directly // make sure we've already adjusted system_server's internal view of itself first updateOomAdjLocked(); try { Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(), Process.THREAD_GROUP_BG_NONINTERACTIVE); Process.THREAD_GROUP_SYSTEM); Process.setThreadGroupAndCpuset(mCompactionThread.getThreadId(), Process.THREAD_GROUP_SYSTEM); } catch (Exception e) { Slog.w(TAG, "Setting background thread cpuset failed"); } Loading Loading @@ -16921,6 +17018,24 @@ public class ActivityManagerService extends IActivityManager.Stub int changes = 0; if (app.curAdj != app.setAdj) { // don't compact during bootup if (mConstants.USE_COMPACTION && mBooted) { // Perform a minor compaction when a perceptible app becomes the prev/home app // Perform a major compaction when any app enters cached // reminder: here, setAdj is previous state, curAdj is upcoming state if (app.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (app.curAdj == ProcessList.PREVIOUS_APP_ADJ || app.curAdj == ProcessList.HOME_APP_ADJ)) { app.reqCompactAction = COMPACT_PROCESS_SOME; mPendingCompactionProcesses.add(app); mCompactionHandler.sendEmptyMessage(COMPACT_PROCESS_MSG); } else if (app.setAdj < ProcessList.CACHED_APP_MIN_ADJ && app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ) { app.reqCompactAction = COMPACT_PROCESS_FULL; mPendingCompactionProcesses.add(app); mCompactionHandler.sendEmptyMessage(COMPACT_PROCESS_MSG); } } ProcessList.setOomAdj(app.pid, app.uid, app.curAdj); if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) { String msg = "Set " + app.pid + " " + app.processName + " adj "
services/core/java/com/android/server/am/EventLogTags.logtags +4 −1 Original line number Diff line number Diff line Loading @@ -136,3 +136,6 @@ option java_package com.android.server.am # The task is being removed from its parent stack 30061 am_remove_task (Task ID|1|5), (Stack ID|1|5) # The task is being compacted 30063 am_compact (Pid|1|5),(Process Name|3),(Action|3),(BeforeRssTotal|2|2),(BeforeRssFile|2|2),(BeforeRssAnon|2|2),(BeforeRssSwap|2|2),(AfterRssTotal|2|2),(AfterRssFile|2|2),(AfterRssAnon|2|2),(AfterRssSwap|2|2),(Time|2|3) No newline at end of file
services/core/java/com/android/server/am/ProcessRecord.java +5 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,9 @@ final class ProcessRecord implements WindowProcessListener { int curAdj; // Current OOM adjustment for this process int setAdj; // Last set OOM adjustment for this process int verifiedAdj; // The last adjustment that was verified as actually being set long lastCompactTime; // The last time that this process was compacted int reqCompactAction; // The most recent compaction action requested for this app. int lastCompactAction; // The most recent compaction action performed for this app. private int mCurSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class int trimMemoryLevel; // Last selected memory trimming level Loading Loading @@ -382,6 +385,8 @@ final class ProcessRecord implements WindowProcessListener { pw.print(" setRaw="); pw.print(setRawAdj); pw.print(" cur="); pw.print(curAdj); pw.print(" set="); pw.println(setAdj); pw.print(prefix); pw.print("lastCompactTime="); pw.print(lastCompactTime); pw.print(" lastCompactAction="); pw.print(lastCompactAction); pw.print(prefix); pw.print("mCurSchedGroup="); pw.print(mCurSchedGroup); pw.print(" setSchedGroup="); pw.print(setSchedGroup); pw.print(" systemNoUi="); pw.print(systemNoUi); Loading