From 6b22279c9c31d4d3de51923853e8dd7c5bc90b20 Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Wed, 11 May 2022 13:03:50 -0700 Subject: [PATCH 1/3] Downgrade compactions after throttle checks This fixes a spammy log issue that happens every time a compaction is requested independently of whether it would end up being discarded due to throttles. Further inspection showed that based on the current throttles moving it to happen post-throttles does not change behavior as throttles work the same way for some and full compactions Bug: 232567934 Test: am compact full Change-Id: Ic886f889c5b8670637b9786112d94c6ad666e8bf --- .../android/server/am/CachedAppOptimizer.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index e49497e8688c0..319260ccff722 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -1223,14 +1223,16 @@ public final class CachedAppOptimizer { break; } - // Downgrade compaction if facing swap memory pressure + // Downgrade compaction under swap memory pressure if (resolvedAction == COMPACT_ACTION_FULL) { - double swapUsagePercent = getFreeSwapPercent(); - if (swapUsagePercent < COMPACT_DOWNGRADE_FREE_SWAP_THRESHOLD) { - Slog.d(TAG_AM, - "Downgraded compaction to file only due to low swap." - + " Swap Free% " + swapUsagePercent); + double swapFreePercent = getFreeSwapPercent(); + if (swapFreePercent < COMPACT_DOWNGRADE_FREE_SWAP_THRESHOLD) { resolvedAction = COMPACT_ACTION_FILE; + if (DEBUG_COMPACTION) { + Slog.d(TAG_AM, + "Downgraded compaction to file only due to low swap." + + " Swap Free% " + swapFreePercent); + } } } @@ -1445,7 +1447,6 @@ public final class CachedAppOptimizer { lastCompactTime = opt.getLastCompactTime(); } - int resolvedAction = resolveCompactionAction(requestedAction); long[] rssBefore; if (pid == 0) { // not a real process, either one being launched or one being killed @@ -1456,17 +1457,17 @@ public final class CachedAppOptimizer { } if (!forceCompaction) { - if (shouldOomAdjThrottleCompaction(proc, resolvedAction)) { + if (shouldOomAdjThrottleCompaction(proc, requestedAction)) { return; } if (shouldTimeThrottleCompaction(proc, start, requestedAction)) { return; } - if (shouldThrottleMiscCompaction(proc, procState, resolvedAction)) { + if (shouldThrottleMiscCompaction(proc, procState, requestedAction)) { return; } rssBefore = mProcessDependencies.getRss(pid); - if (shouldRssThrottleCompaction(resolvedAction, pid, name, rssBefore)) { + if (shouldRssThrottleCompaction(requestedAction, pid, name, rssBefore)) { return; } } else { @@ -1494,6 +1495,8 @@ public final class CachedAppOptimizer { default: break; } + + int resolvedAction = resolveCompactionAction(requestedAction); action = compactActionIntToString(resolvedAction); try { From 414923e81aed6e4a7654dfcb5bba0ac2d46314eb Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Wed, 11 May 2022 15:24:48 -0700 Subject: [PATCH 2/3] Add some compaction statistics around throttling Adding some statistics that can be helpful on bugreports for finding when compaction is being over triggered. Bug: 232296251 Test: dumpsys activity Change-Id: I686aa2501cc8781c5939260a00bfda380890bf08 --- .../android/server/am/CachedAppOptimizer.java | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 319260ccff722..53777ef95c31c 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -341,10 +341,24 @@ public final class CachedAppOptimizer { } }; + // Compaction Stats private int mSomeCompactionCount; private int mFullCompactionCount; private int mPersistentCompactionCount; private int mBfgsCompactionCount; + private long mSomeCompactRequest; + private long mFullCompactRequest; + private long mPersistentCompactRequest; + private long mBfgsCompactRequest; + private long mProcCompactionsRequested; + private long mProcCompactionsPerformed; + private long mProcCompactionsNoPidThrottled; + private long mProcCompactionsOomAdjThrottled; + private long mProcCompactionsTimeThrottled; + private long mProcCompactionsRSSThrottled; + private long mProcCompactionsMiscThrottled; + private long mSystemCompactionsPerformed; + private final ProcessDependencies mProcessDependencies; private final ProcLocksReader mProcLocksReader; @@ -436,9 +450,31 @@ public final class CachedAppOptimizer { pw.println(" " + KEY_COMPACT_PROC_STATE_THROTTLE + "=" + Arrays.toString(mProcStateThrottle.toArray(new Integer[0]))); - pw.println(" " + mSomeCompactionCount + " some, " + mFullCompactionCount + pw.println(" Requested: " + mSomeCompactRequest + " some, " + mFullCompactRequest + + " full, " + mPersistentCompactRequest + " persistent, " + + mBfgsCompactRequest + " BFGS compactions."); + pw.println(" Performed: " + mSomeCompactionCount + " some, " + mFullCompactionCount + " full, " + mPersistentCompactionCount + " persistent, " + mBfgsCompactionCount + " BFGS compactions."); + pw.println(" Process Compactions Requested: " + mProcCompactionsRequested); + pw.println(" Process Compactions Performed: " + mProcCompactionsPerformed); + long compactionsThrottled = mProcCompactionsRequested - mProcCompactionsPerformed; + pw.println(" Process Compactions Throttled: " + compactionsThrottled); + double compactThrottlePercentage = + (compactionsThrottled / (double) mProcCompactionsRequested) * 100.0; + pw.println(" Process Compactions Throttle Percentage: " + compactThrottlePercentage); + pw.println(" NoPid Throttled: " + mProcCompactionsNoPidThrottled); + pw.println(" OomAdj Throttled: " + mProcCompactionsOomAdjThrottled); + pw.println(" Time Throttled: " + mProcCompactionsTimeThrottled); + pw.println(" RSS Throttled: " + mProcCompactionsRSSThrottled); + pw.println(" Misc Throttled: " + mProcCompactionsMiscThrottled); + long unaccountedThrottled = compactionsThrottled - mProcCompactionsNoPidThrottled + - mProcCompactionsOomAdjThrottled - mProcCompactionsTimeThrottled + - mProcCompactionsRSSThrottled - mProcCompactionsMiscThrottled; + // Any throttle that was not part of the previous categories + pw.println(" Unaccounted Throttled: " + unaccountedThrottled); + + pw.println(" System Compactions Performed: " + mSystemCompactionsPerformed); pw.println(" Tracking last compaction stats for " + mLastCompactionStats.size() + " processes."); @@ -479,6 +515,7 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppSome(ProcessRecord app, boolean force) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_SOME); + ++mSomeCompactRequest; compactApp(app, force, "some"); } @@ -519,6 +556,7 @@ public final class CachedAppOptimizer { " compactAppFull requested for " + app.processName + " force: " + force + " oomAdjEnteredCached: " + oomAdjEnteredCached); } + ++mFullCompactRequest; // Apply OOM adj score throttle for Full App Compaction. if (force || oomAdjEnteredCached) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_FULL); @@ -535,6 +573,7 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppPersistent(ProcessRecord app) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_PERSISTENT); + ++mPersistentCompactRequest; compactApp(app, false, "Persistent"); } @@ -573,6 +612,7 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppBfgs(ProcessRecord app) { + ++mBfgsCompactRequest; app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_BFGS); compactApp(app, false, " Bfgs"); } @@ -1447,27 +1487,33 @@ public final class CachedAppOptimizer { lastCompactTime = opt.getLastCompactTime(); } + ++mProcCompactionsRequested; long[] rssBefore; if (pid == 0) { // not a real process, either one being launched or one being killed if (DEBUG_COMPACTION) { Slog.d(TAG_AM, "Compaction failed, pid is 0"); } + ++mProcCompactionsNoPidThrottled; return; } if (!forceCompaction) { if (shouldOomAdjThrottleCompaction(proc, requestedAction)) { + ++mProcCompactionsOomAdjThrottled; return; } if (shouldTimeThrottleCompaction(proc, start, requestedAction)) { + ++mProcCompactionsTimeThrottled; return; } if (shouldThrottleMiscCompaction(proc, procState, requestedAction)) { + ++mProcCompactionsMiscThrottled; return; } rssBefore = mProcessDependencies.getRss(pid); if (shouldRssThrottleCompaction(requestedAction, pid, name, rssBefore)) { + ++mProcCompactionsRSSThrottled; return; } } else { @@ -1502,6 +1548,7 @@ public final class CachedAppOptimizer { try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Compact " + action + ": " + name); + ++mProcCompactionsPerformed; long zramFreeKbBefore = Debug.getZramFreeKb(); mProcessDependencies.performCompaction(action, pid); long[] rssAfter = mProcessDependencies.getRss(pid); @@ -1553,6 +1600,7 @@ public final class CachedAppOptimizer { break; } case COMPACT_SYSTEM_MSG: { + ++mSystemCompactionsPerformed; Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem"); compactSystem(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); From 7f4d90343c6b3799ddbd1f1d5c854bd14f49464e Mon Sep 17 00:00:00 2001 From: Edgar Arriaga Date: Wed, 11 May 2022 18:32:19 -0700 Subject: [PATCH 3/3] Avoid full compaction when apps move within Cached bucket This patch reduces the amount of times we trigger full compactions that currently happen at any OOM adjust change when the app is within the Cached state bucket as it was identified that there were many instances of this situation. Bug: 232311101 Test: Checked that the number of full compactions went down in dumpsys activity Change-Id: If4995432cbf770227ebd60dad2889522d98b103d --- .../core/java/com/android/server/am/CachedAppOptimizer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 53777ef95c31c..c88d82cf0cf2c 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -1235,7 +1235,8 @@ public final class CachedAppOptimizer { && (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) { // Perform a minor compaction when a perceptible app becomes the prev/home app compactAppSome(app, false); - } else if (newAdj >= ProcessList.CACHED_APP_MIN_ADJ + } else if (oldAdj < ProcessList.CACHED_APP_MIN_ADJ + && newAdj >= ProcessList.CACHED_APP_MIN_ADJ && newAdj <= ProcessList.CACHED_APP_MAX_ADJ) { // Perform a major compaction when any app enters cached compactAppFull(app, false);