diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index c5f082a0f9e37..1839e2a9cee4e 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -382,10 +382,13 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppSome(ProcessRecord app) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_SOME); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( - COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState())); + if (!app.mOptRecord.hasPendingCompact()) { + app.mOptRecord.setHasPendingCompact(true); + mPendingCompactionProcesses.add(app); + mCompactionHandler.sendMessage( + mCompactionHandler.obtainMessage( + COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState())); + } } @GuardedBy("mProcLock") @@ -396,10 +399,13 @@ public final class CachedAppOptimizer { && app.mState.getCurAdj() >= mCompactThrottleMinOomAdj && app.mState.getCurAdj() <= mCompactThrottleMaxOomAdj) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_FULL); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( - COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState())); + if (!app.mOptRecord.hasPendingCompact()) { + app.mOptRecord.setHasPendingCompact(true); + mPendingCompactionProcesses.add(app); + mCompactionHandler.sendMessage( + mCompactionHandler.obtainMessage( + COMPACT_PROCESS_MSG, app.mState.getSetAdj(), app.mState.getSetProcState())); + } } else { if (DEBUG_COMPACTION) { Slog.d(TAG_AM, "Skipping full compaction for " + app.processName @@ -412,10 +418,13 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppPersistent(ProcessRecord app) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_PERSISTENT); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( + if (!app.mOptRecord.hasPendingCompact()) { + app.mOptRecord.setHasPendingCompact(true); + mPendingCompactionProcesses.add(app); + mCompactionHandler.sendMessage( + mCompactionHandler.obtainMessage( COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState())); + } } @GuardedBy("mProcLock") @@ -427,10 +436,13 @@ public final class CachedAppOptimizer { @GuardedBy("mProcLock") void compactAppBfgs(ProcessRecord app) { app.mOptRecord.setReqCompactAction(COMPACT_PROCESS_BFGS); - mPendingCompactionProcesses.add(app); - mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( + if (!app.mOptRecord.hasPendingCompact()) { + app.mOptRecord.setHasPendingCompact(true); + mPendingCompactionProcesses.add(app); + mCompactionHandler.sendMessage( + mCompactionHandler.obtainMessage( COMPACT_PROCESS_MSG, app.mState.getCurAdj(), app.mState.getSetProcState())); + } } @GuardedBy("mProcLock") @@ -954,6 +966,7 @@ public final class CachedAppOptimizer { pendingAction = opt.getReqCompactAction(); pid = proc.getPid(); name = proc.processName; + opt.setHasPendingCompact(false); // don't compact if the process has returned to perceptible // and this is only a cached/home/prev compaction diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java index 464361076dc80..f4ce7230f72ad 100644 --- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java +++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java @@ -46,6 +46,12 @@ final class ProcessCachedOptimizerRecord { @GuardedBy("mProcLock") private int mLastCompactAction; + /** + * This process has been scheduled for a memory compaction. + */ + @GuardedBy("mProcLock") + private boolean mPendingCompact; + /** * True when the process is frozen. */ @@ -100,6 +106,16 @@ final class ProcessCachedOptimizerRecord { mLastCompactAction = lastCompactAction; } + @GuardedBy("mProcLock") + boolean hasPendingCompact() { + return mPendingCompact; + } + + @GuardedBy("mProcLock") + void setHasPendingCompact(boolean pendingCompact) { + mPendingCompact = pendingCompact; + } + @GuardedBy("mProcLock") boolean isFrozen() { return mFrozen;