Loading services/core/java/com/android/server/am/CachedAppOptimizer.java +33 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,8 @@ public final class CachedAppOptimizer { */ static private native void compactProcess(int pid, int compactionFlags); static private native void cancelCompaction(); /** * Reads the flag value from DeviceConfig to determine whether app compaction * should be enabled, and starts the freeze/compaction thread if needed. Loading Loading @@ -1049,6 +1051,26 @@ public final class CachedAppOptimizer { } } @GuardedBy({"mService", "mProcLock"}) void onOomAdjustChanged(int oldAdj, int newAdj, ProcessRecord app) { // Cancel any currently executing compactions // if the process moved out of cached state if (DefaultProcessDependencies.mPidCompacting == app.mPid && newAdj < oldAdj && newAdj < ProcessList.CACHED_APP_MIN_ADJ) { cancelCompaction(); } // Perform a minor compaction when a perceptible app becomes the prev/home app // Perform a major compaction when any app enters cached if (oldAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) { compactAppSome(app); } else if (newAdj >= ProcessList.CACHED_APP_MIN_ADJ && newAdj <= ProcessList.CACHED_APP_MAX_ADJ) { compactAppFull(app); } } @VisibleForTesting static final class LastCompactionStats { private final long[] mRssAfterCompaction; Loading Loading @@ -1091,6 +1113,13 @@ public final class CachedAppOptimizer { name = proc.processName; opt.setHasPendingCompact(false); if (mAm.mInternal.isPendingTopUid(proc.uid)) { // In case the OOM Adjust has not yet been propagated we see if this is // pending on becoming top app in which case we should not compact. Slog.e(TAG_AM, "Skip compaction since UID is active for " + name); return; } // don't compact if the process has returned to perceptible // and this is only a cached/home/prev compaction if ((pendingAction == COMPACT_PROCESS_SOME Loading Loading @@ -1500,6 +1529,8 @@ public final class CachedAppOptimizer { * Default implementation for ProcessDependencies, public vor visibility to OomAdjuster class. */ private static final class DefaultProcessDependencies implements ProcessDependencies { public static int mPidCompacting = -1; // Get memory RSS from process. @Override public long[] getRss(int pid) { Loading @@ -1509,6 +1540,7 @@ public final class CachedAppOptimizer { // Compact process. @Override public void performCompaction(String action, int pid) throws IOException { mPidCompacting = pid; if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FULL])) { compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG); } else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FILE])) { Loading @@ -1516,6 +1548,7 @@ public final class CachedAppOptimizer { } else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_ANON])) { compactProcess(pid, COMPACT_ACTION_ANON_FLAG); } mPidCompacting = -1; } } } services/core/java/com/android/server/am/OomAdjuster.java +2 −11 Original line number Diff line number Diff line Loading @@ -2486,18 +2486,9 @@ public class OomAdjuster { // don't compact during bootup if (mCachedAppOptimizer.useCompaction() && mService.mBooted) { // Cached and prev/home compaction if (state.getCurAdj() != state.getSetAdj()) { // 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 (state.getSetAdj() <= ProcessList.PERCEPTIBLE_APP_ADJ && (state.getCurAdj() == ProcessList.PREVIOUS_APP_ADJ || state.getCurAdj() == ProcessList.HOME_APP_ADJ)) { mCachedAppOptimizer.compactAppSome(app); } else if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && state.getCurAdj() <= ProcessList.CACHED_APP_MAX_ADJ) { mCachedAppOptimizer.compactAppFull(app); } if (state.getCurAdj() != state.getSetAdj()) { mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app); } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE && state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ // Because these can fire independent of oom_adj/procstate changes, we need Loading services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,9 @@ using android::base::unique_fd; namespace android { static bool cancelRunningCompaction; static bool compactionInProgress; // Legacy method for compacting processes, any new code should // use compactProcess instead. static inline void compactProcessProcfs(int pid, const std::string& compactionType) { Loading @@ -83,9 +86,18 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT // Skip compaction if failed to open pidfd with any error return -errno; } compactionInProgress = true; cancelRunningCompaction = false; int64_t totalBytesCompacted = 0; for (int iBase = 0; iBase < vmas.size(); iBase += UIO_MAXIOV) { if (CC_UNLIKELY(cancelRunningCompaction)) { // There could be a significant delay betweenwhen a compaction // is requested and when it is handled during this time // our OOM adjust could have improved. cancelRunningCompaction = false; break; } int totalVmasToKernel = std::min(UIO_MAXIOV, (int)(vmas.size() - iBase)); for (int iVec = 0, iVma = iBase; iVec < totalVmasToKernel; ++iVec, ++iVma) { vmasToKernel[iVec].iov_base = (void*)vmas[iVma].start; Loading @@ -95,11 +107,13 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT auto bytesCompacted = process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0); if (CC_UNLIKELY(bytesCompacted == -1)) { compactionInProgress = false; return -errno; } totalBytesCompacted += bytesCompacted; } compactionInProgress = false; return totalBytesCompacted; } Loading Loading @@ -228,6 +242,12 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job } } static void com_android_server_am_CachedAppOptimizer_cancelCompaction(JNIEnv*, jobject) { if (compactionInProgress) { cancelRunningCompaction = true; } } static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, jobject, jint pid, jint compactionFlags) { compactProcessOrFallback(pid, compactionFlags); Loading Loading @@ -279,6 +299,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"cancelCompaction", "()V", (void*)com_android_server_am_CachedAppOptimizer_cancelCompaction}, {"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}, Loading Loading
services/core/java/com/android/server/am/CachedAppOptimizer.java +33 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,8 @@ public final class CachedAppOptimizer { */ static private native void compactProcess(int pid, int compactionFlags); static private native void cancelCompaction(); /** * Reads the flag value from DeviceConfig to determine whether app compaction * should be enabled, and starts the freeze/compaction thread if needed. Loading Loading @@ -1049,6 +1051,26 @@ public final class CachedAppOptimizer { } } @GuardedBy({"mService", "mProcLock"}) void onOomAdjustChanged(int oldAdj, int newAdj, ProcessRecord app) { // Cancel any currently executing compactions // if the process moved out of cached state if (DefaultProcessDependencies.mPidCompacting == app.mPid && newAdj < oldAdj && newAdj < ProcessList.CACHED_APP_MIN_ADJ) { cancelCompaction(); } // Perform a minor compaction when a perceptible app becomes the prev/home app // Perform a major compaction when any app enters cached if (oldAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (newAdj == ProcessList.PREVIOUS_APP_ADJ || newAdj == ProcessList.HOME_APP_ADJ)) { compactAppSome(app); } else if (newAdj >= ProcessList.CACHED_APP_MIN_ADJ && newAdj <= ProcessList.CACHED_APP_MAX_ADJ) { compactAppFull(app); } } @VisibleForTesting static final class LastCompactionStats { private final long[] mRssAfterCompaction; Loading Loading @@ -1091,6 +1113,13 @@ public final class CachedAppOptimizer { name = proc.processName; opt.setHasPendingCompact(false); if (mAm.mInternal.isPendingTopUid(proc.uid)) { // In case the OOM Adjust has not yet been propagated we see if this is // pending on becoming top app in which case we should not compact. Slog.e(TAG_AM, "Skip compaction since UID is active for " + name); return; } // don't compact if the process has returned to perceptible // and this is only a cached/home/prev compaction if ((pendingAction == COMPACT_PROCESS_SOME Loading Loading @@ -1500,6 +1529,8 @@ public final class CachedAppOptimizer { * Default implementation for ProcessDependencies, public vor visibility to OomAdjuster class. */ private static final class DefaultProcessDependencies implements ProcessDependencies { public static int mPidCompacting = -1; // Get memory RSS from process. @Override public long[] getRss(int pid) { Loading @@ -1509,6 +1540,7 @@ public final class CachedAppOptimizer { // Compact process. @Override public void performCompaction(String action, int pid) throws IOException { mPidCompacting = pid; if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FULL])) { compactProcess(pid, COMPACT_ACTION_FILE_FLAG | COMPACT_ACTION_ANON_FLAG); } else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_FILE])) { Loading @@ -1516,6 +1548,7 @@ public final class CachedAppOptimizer { } else if (action.equals(COMPACT_ACTION_STRING[COMPACT_ACTION_ANON])) { compactProcess(pid, COMPACT_ACTION_ANON_FLAG); } mPidCompacting = -1; } } }
services/core/java/com/android/server/am/OomAdjuster.java +2 −11 Original line number Diff line number Diff line Loading @@ -2486,18 +2486,9 @@ public class OomAdjuster { // don't compact during bootup if (mCachedAppOptimizer.useCompaction() && mService.mBooted) { // Cached and prev/home compaction if (state.getCurAdj() != state.getSetAdj()) { // 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 (state.getSetAdj() <= ProcessList.PERCEPTIBLE_APP_ADJ && (state.getCurAdj() == ProcessList.PREVIOUS_APP_ADJ || state.getCurAdj() == ProcessList.HOME_APP_ADJ)) { mCachedAppOptimizer.compactAppSome(app); } else if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && state.getCurAdj() <= ProcessList.CACHED_APP_MAX_ADJ) { mCachedAppOptimizer.compactAppFull(app); } if (state.getCurAdj() != state.getSetAdj()) { mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app); } else if (mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE && state.getSetAdj() < ProcessList.FOREGROUND_APP_ADJ // Because these can fire independent of oom_adj/procstate changes, we need Loading
services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,9 @@ using android::base::unique_fd; namespace android { static bool cancelRunningCompaction; static bool compactionInProgress; // Legacy method for compacting processes, any new code should // use compactProcess instead. static inline void compactProcessProcfs(int pid, const std::string& compactionType) { Loading @@ -83,9 +86,18 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT // Skip compaction if failed to open pidfd with any error return -errno; } compactionInProgress = true; cancelRunningCompaction = false; int64_t totalBytesCompacted = 0; for (int iBase = 0; iBase < vmas.size(); iBase += UIO_MAXIOV) { if (CC_UNLIKELY(cancelRunningCompaction)) { // There could be a significant delay betweenwhen a compaction // is requested and when it is handled during this time // our OOM adjust could have improved. cancelRunningCompaction = false; break; } int totalVmasToKernel = std::min(UIO_MAXIOV, (int)(vmas.size() - iBase)); for (int iVec = 0, iVma = iBase; iVec < totalVmasToKernel; ++iVec, ++iVma) { vmasToKernel[iVec].iov_base = (void*)vmas[iVma].start; Loading @@ -95,11 +107,13 @@ static int64_t compactMemory(const std::vector<Vma>& vmas, int pid, int madviseT auto bytesCompacted = process_madvise(pidfd, vmasToKernel, totalVmasToKernel, madviseType, 0); if (CC_UNLIKELY(bytesCompacted == -1)) { compactionInProgress = false; return -errno; } totalBytesCompacted += bytesCompacted; } compactionInProgress = false; return totalBytesCompacted; } Loading Loading @@ -228,6 +242,12 @@ static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, job } } static void com_android_server_am_CachedAppOptimizer_cancelCompaction(JNIEnv*, jobject) { if (compactionInProgress) { cancelRunningCompaction = true; } } static void com_android_server_am_CachedAppOptimizer_compactProcess(JNIEnv*, jobject, jint pid, jint compactionFlags) { compactProcessOrFallback(pid, compactionFlags); Loading Loading @@ -279,6 +299,8 @@ static jstring com_android_server_am_CachedAppOptimizer_getFreezerCheckPath(JNIE static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"cancelCompaction", "()V", (void*)com_android_server_am_CachedAppOptimizer_cancelCompaction}, {"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}, Loading