diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index ff569a681a4e4..d0f9e3d6c11c5 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -152,6 +152,11 @@ public final class CachedAppOptimizer { static final int SET_FROZEN_PROCESS_MSG = 3; static final int REPORT_UNFREEZE_MSG = 4; + // When free swap falls below this percentage threshold any full (file + anon) + // compactions will be downgraded to file only compactions to reduce pressure + // on swap resources as file. + static final double COMPACT_DOWNGRADE_FREE_SWAP_THRESHOLD = 0.2; + static final int DO_FREEZE = 1; static final int REPORT_UNFREEZE = 2; @@ -544,6 +549,11 @@ public final class CachedAppOptimizer { static private native void cancelCompaction(); + /** + * Retrieves the free swap percentage. + */ + static private native double getFreeSwapPercent(); + /** * Reads the flag value from DeviceConfig to determine whether app compaction * should be enabled, and starts the freeze/compaction thread if needed. @@ -1338,6 +1348,18 @@ public final class CachedAppOptimizer { default: break; } + // Downgrade compaction if facing swap memory pressure + if (action.equals(mCompactActionFull)) { + 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); + action = mCompactActionSome; + pendingAction = COMPACT_PROCESS_SOME; + } + } + try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Compact " + ((pendingAction == COMPACT_PROCESS_SOME) ? "some" : "full") diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 636ca4143a33c..6138e840a507b 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -305,6 +306,16 @@ static void com_android_server_am_CachedAppOptimizer_cancelCompaction(JNIEnv*, j } } +static jdouble com_android_server_am_CachedAppOptimizer_getFreeSwapPercent(JNIEnv*, jobject) { + struct sysinfo memoryInfo; + int error = sysinfo(&memoryInfo); + if(error == -1) { + LOG(ERROR) << "Could not check free swap space"; + return 0; + } + return (double)memoryInfo.freeswap / (double)memoryInfo.totalswap; +} + static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, jobject, jint pid, jint compactionFlags) { compactProcessOrFallback(pid, compactionFlags); @@ -358,6 +369,8 @@ static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"cancelCompaction", "()V", (void*)com_android_server_am_CachedAppOptimizer_cancelCompaction}, + {"getFreeSwapPercent", "()D", + (void*)com_android_server_am_CachedAppOptimizer_getFreeSwapPercent}, {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, {"compactProcess", "(II)V", (void*)com_android_server_am_CachedAppOptimizer_compactProcess}, {"freezeBinder", "(IZ)I", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder},