Fix potential freezer thrashing
Currently a pending DO_FREEZE message stays in the message queue until AMS tries to actually freeze it. If the OOM_ADJ happens to swing back and forth, the app might be frozen and then unfrozen quickly. Fix the issue by removing the pending DO_FREEZE message ASAP. Bug: 188739027 Test: Move an app to foreground, its pending freeze status is cleared. Change-Id: I369710d408e1d81bc169a620543909cb4ae6edf7
This commit is contained in:
@@ -881,7 +881,8 @@ public final class CachedAppOptimizer {
|
||||
|
||||
@GuardedBy({"mAm", "mProcLock"})
|
||||
void freezeAppAsyncLSP(ProcessRecord app) {
|
||||
if (mFreezeHandler.hasMessages(SET_FROZEN_PROCESS_MSG, app)) {
|
||||
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
|
||||
if (opt.isPendingFreeze()) {
|
||||
// Skip redundant DO_FREEZE message
|
||||
return;
|
||||
}
|
||||
@@ -890,21 +891,27 @@ public final class CachedAppOptimizer {
|
||||
mFreezeHandler.obtainMessage(
|
||||
SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app),
|
||||
mFreezerDebounceTimeout);
|
||||
opt.setPendingFreeze(true);
|
||||
if (DEBUG_FREEZER) {
|
||||
Slog.d(TAG_AM, "Async freezing " + app.getPid() + " " + app.processName);
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy({"mAm", "mProcLock"})
|
||||
void unfreezeAppLSP(ProcessRecord app) {
|
||||
mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app);
|
||||
|
||||
final int pid = app.getPid();
|
||||
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
|
||||
if (opt.isPendingFreeze()) {
|
||||
// Remove pending DO_FREEZE message
|
||||
mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app);
|
||||
opt.setPendingFreeze(false);
|
||||
if (DEBUG_FREEZER) {
|
||||
Slog.d(TAG_AM, "Cancel freezing " + pid + " " + app.processName);
|
||||
}
|
||||
}
|
||||
|
||||
opt.setFreezerOverride(false);
|
||||
if (!opt.isFrozen()) {
|
||||
if (DEBUG_FREEZER) {
|
||||
Slog.d(TAG_AM,
|
||||
"Skipping unfreeze for process " + pid + " "
|
||||
+ app.processName + " (not frozen)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -983,7 +990,12 @@ public final class CachedAppOptimizer {
|
||||
@GuardedBy({"mAm", "mProcLock"})
|
||||
void unscheduleFreezeAppLSP(ProcessRecord app) {
|
||||
if (mUseFreezer) {
|
||||
mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app);
|
||||
final ProcessCachedOptimizerRecord opt = app.mOptRecord;
|
||||
if (opt.isPendingFreeze()) {
|
||||
// Remove pending DO_FREEZE message
|
||||
mFreezeHandler.removeMessages(SET_FROZEN_PROCESS_MSG, app);
|
||||
opt.setPendingFreeze(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1278,6 +1290,8 @@ public final class CachedAppOptimizer {
|
||||
final boolean frozen;
|
||||
final ProcessCachedOptimizerRecord opt = proc.mOptRecord;
|
||||
|
||||
opt.setPendingFreeze(false);
|
||||
|
||||
try {
|
||||
// pre-check for locks to avoid unnecessary freeze/unfreeze operations
|
||||
if (Process.hasFileLocks(pid)) {
|
||||
@@ -1352,7 +1366,6 @@ public final class CachedAppOptimizer {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (DEBUG_FREEZER) {
|
||||
Slog.d(TAG_AM, "froze " + pid + " " + name);
|
||||
}
|
||||
|
||||
@@ -3112,6 +3112,7 @@ public class OomAdjuster {
|
||||
// if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze
|
||||
if (opt.isFrozen() && opt.shouldNotFreeze()) {
|
||||
mCachedAppOptimizer.unfreezeAppLSP(app);
|
||||
return;
|
||||
}
|
||||
|
||||
final ProcessStateRecord state = app.mState;
|
||||
@@ -3119,7 +3120,7 @@ public class OomAdjuster {
|
||||
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
|
||||
&& !opt.shouldNotFreeze()) {
|
||||
mCachedAppOptimizer.freezeAppAsyncLSP(app);
|
||||
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ && opt.isFrozen()) {
|
||||
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
|
||||
mCachedAppOptimizer.unfreezeAppLSP(app);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,12 @@ final class ProcessCachedOptimizerRecord {
|
||||
@GuardedBy("mProcLock")
|
||||
private boolean mFreezeExempt;
|
||||
|
||||
/**
|
||||
* This process has been scheduled for freezing
|
||||
*/
|
||||
@GuardedBy("mProcLock")
|
||||
private boolean mPendingFreeze;
|
||||
|
||||
@GuardedBy("mProcLock")
|
||||
long getLastCompactTime() {
|
||||
return mLastCompactTime;
|
||||
@@ -171,6 +177,16 @@ final class ProcessCachedOptimizerRecord {
|
||||
return mFreezeExempt;
|
||||
}
|
||||
|
||||
@GuardedBy("mProcLock")
|
||||
void setPendingFreeze(boolean freeze) {
|
||||
mPendingFreeze = freeze;
|
||||
}
|
||||
|
||||
@GuardedBy("mProcLock")
|
||||
boolean isPendingFreeze() {
|
||||
return mPendingFreeze;
|
||||
}
|
||||
|
||||
@GuardedBy("mProcLock")
|
||||
void setFreezeExempt(boolean exempt) {
|
||||
mFreezeExempt = exempt;
|
||||
@@ -190,6 +206,7 @@ final class ProcessCachedOptimizerRecord {
|
||||
pw.print(prefix); pw.print("lastCompactTime="); pw.print(mLastCompactTime);
|
||||
pw.print(" lastCompactAction="); pw.println(mLastCompactAction);
|
||||
pw.print(prefix); pw.print("isFreezeExempt="); pw.print(mFreezeExempt);
|
||||
pw.print(" isPendingFreeze="); pw.print(mPendingFreeze);
|
||||
pw.print(" " + IS_FROZEN + "="); pw.println(mFrozen);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user