Merge changes from topic "CacheOomRanker-new-features-sc-qpr1-dev" into sc-qpr1-dev am: 78c1e444ab

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15771575

Change-Id: I133e07606db26a5c92a4901165b0c59250cf8b50
This commit is contained in:
Misha Wagner
2021-09-21 09:13:09 +00:00
committed by Automerger Merge Worker
3 changed files with 293 additions and 6 deletions

View File

@@ -16,6 +16,8 @@
package com.android.server.am; package com.android.server.am;
import android.os.Process;
import android.os.SystemClock;
import android.provider.DeviceConfig; import android.provider.DeviceConfig;
import android.util.Slog; import android.util.Slog;
@@ -46,6 +48,14 @@ public class CacheOomRanker {
@VisibleForTesting @VisibleForTesting
static final int DEFAULT_PRESERVE_TOP_N_APPS = 3; static final int DEFAULT_PRESERVE_TOP_N_APPS = 3;
@VisibleForTesting @VisibleForTesting
static final String KEY_OOM_RE_RANKING_USE_FREQUENT_RSS = "oom_re_ranking_rss_use_frequent_rss";
@VisibleForTesting
static final boolean DEFAULT_USE_FREQUENT_RSS = true;
@VisibleForTesting
static final String KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS = "oom_re_ranking_rss_update_rate_ms";
@VisibleForTesting
static final long DEFAULT_RSS_UPDATE_RATE_MS = 10_000; // 10 seconds
@VisibleForTesting
static final String KEY_OOM_RE_RANKING_LRU_WEIGHT = "oom_re_ranking_lru_weight"; static final String KEY_OOM_RE_RANKING_LRU_WEIGHT = "oom_re_ranking_lru_weight";
@VisibleForTesting @VisibleForTesting
static final float DEFAULT_OOM_RE_RANKING_LRU_WEIGHT = 0.35f; static final float DEFAULT_OOM_RE_RANKING_LRU_WEIGHT = 0.35f;
@@ -62,6 +72,8 @@ public class CacheOomRanker {
new ScoreComparator(); new ScoreComparator();
private static final Comparator<RankedProcessRecord> CACHE_USE_COMPARATOR = private static final Comparator<RankedProcessRecord> CACHE_USE_COMPARATOR =
new CacheUseComparator(); new CacheUseComparator();
private static final Comparator<RankedProcessRecord> RSS_COMPARATOR =
new RssComparator();
private static final Comparator<RankedProcessRecord> LAST_RSS_COMPARATOR = private static final Comparator<RankedProcessRecord> LAST_RSS_COMPARATOR =
new LastRssComparator(); new LastRssComparator();
private static final Comparator<RankedProcessRecord> LAST_ACTIVITY_TIME_COMPARATOR = private static final Comparator<RankedProcessRecord> LAST_ACTIVITY_TIME_COMPARATOR =
@@ -70,6 +82,7 @@ public class CacheOomRanker {
private final Object mPhenotypeFlagLock = new Object(); private final Object mPhenotypeFlagLock = new Object();
private final ActivityManagerService mService; private final ActivityManagerService mService;
private final ProcessDependencies mProcessDependencies;
private final ActivityManagerGlobalLock mProcLock; private final ActivityManagerGlobalLock mProcLock;
private final Object mProfilerLock; private final Object mProfilerLock;
@@ -78,6 +91,12 @@ public class CacheOomRanker {
@GuardedBy("mPhenotypeFlagLock") @GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting @VisibleForTesting
int mPreserveTopNApps = DEFAULT_PRESERVE_TOP_N_APPS; int mPreserveTopNApps = DEFAULT_PRESERVE_TOP_N_APPS;
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting
boolean mUseFrequentRss = DEFAULT_USE_FREQUENT_RSS;
@GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting
long mRssUpdateRateMs = DEFAULT_RSS_UPDATE_RATE_MS;
// Weight to apply to the LRU ordering. // Weight to apply to the LRU ordering.
@GuardedBy("mPhenotypeFlagLock") @GuardedBy("mPhenotypeFlagLock")
@VisibleForTesting @VisibleForTesting
@@ -110,6 +129,10 @@ public class CacheOomRanker {
updateNumberToReRank(); updateNumberToReRank();
} else if (KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS.equals(name)) { } else if (KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS.equals(name)) {
updatePreserveTopNApps(); updatePreserveTopNApps();
} else if (KEY_OOM_RE_RANKING_USE_FREQUENT_RSS.equals(name)) {
updateUseFrequentRss();
} else if (KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS.equals(name)) {
updateRssUpdateRateMs();
} else if (KEY_OOM_RE_RANKING_LRU_WEIGHT.equals(name)) { } else if (KEY_OOM_RE_RANKING_LRU_WEIGHT.equals(name)) {
updateLruWeight(); updateLruWeight();
} else if (KEY_OOM_RE_RANKING_USES_WEIGHT.equals(name)) { } else if (KEY_OOM_RE_RANKING_USES_WEIGHT.equals(name)) {
@@ -123,9 +146,15 @@ public class CacheOomRanker {
}; };
CacheOomRanker(final ActivityManagerService service) { CacheOomRanker(final ActivityManagerService service) {
this(service, new ProcessDependenciesImpl());
}
@VisibleForTesting
CacheOomRanker(final ActivityManagerService service, ProcessDependencies processDependencies) {
mService = service; mService = service;
mProcLock = service.mProcLock; mProcLock = service.mProcLock;
mProfilerLock = service.mAppProfiler.mProfilerLock; mProfilerLock = service.mAppProfiler.mProfilerLock;
mProcessDependencies = processDependencies;
} }
/** Load settings from device config and register a listener for changes. */ /** Load settings from device config and register a listener for changes. */
@@ -189,6 +218,18 @@ public class CacheOomRanker {
mPreserveTopNApps = preserveTopNApps; mPreserveTopNApps = preserveTopNApps;
} }
@GuardedBy("mPhenotypeFlagLock")
private void updateRssUpdateRateMs() {
mRssUpdateRateMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS, DEFAULT_RSS_UPDATE_RATE_MS);
}
@GuardedBy("mPhenotypeFlagLock")
private void updateUseFrequentRss() {
mUseFrequentRss = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_OOM_RE_RANKING_USE_FREQUENT_RSS, DEFAULT_USE_FREQUENT_RSS);
}
@GuardedBy("mPhenotypeFlagLock") @GuardedBy("mPhenotypeFlagLock")
private void updateLruWeight() { private void updateLruWeight() {
mLruWeight = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, mLruWeight = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -244,6 +285,8 @@ public class CacheOomRanker {
float usesWeight; float usesWeight;
float rssWeight; float rssWeight;
int preserveTopNApps; int preserveTopNApps;
boolean useFrequentRss;
long rssUpdateRateMs;
int[] lruPositions; int[] lruPositions;
RankedProcessRecord[] scoredProcessRecords; RankedProcessRecord[] scoredProcessRecords;
@@ -252,6 +295,8 @@ public class CacheOomRanker {
usesWeight = mUsesWeight; usesWeight = mUsesWeight;
rssWeight = mRssWeight; rssWeight = mRssWeight;
preserveTopNApps = mPreserveTopNApps; preserveTopNApps = mPreserveTopNApps;
useFrequentRss = mUseFrequentRss;
rssUpdateRateMs = mRssUpdateRateMs;
lruPositions = mLruPositions; lruPositions = mLruPositions;
scoredProcessRecords = mScoredProcessRecords; scoredProcessRecords = mScoredProcessRecords;
} }
@@ -296,6 +341,33 @@ public class CacheOomRanker {
} }
} }
if (useFrequentRss) {
// Update RSS values for re-ranked apps.
long nowMs = SystemClock.elapsedRealtime();
for (int i = 0; i < numProcessesReRanked; ++i) {
RankedProcessRecord scoredProcessRecord = scoredProcessRecords[i];
long sinceUpdateMs =
nowMs - scoredProcessRecord.proc.mState.getCacheOomRankerRssTimeMs();
if (scoredProcessRecord.proc.mState.getCacheOomRankerRss() != 0
&& sinceUpdateMs < rssUpdateRateMs) {
continue;
}
long[] rss = mProcessDependencies.getRss(scoredProcessRecord.proc.getPid());
if (rss == null || rss.length == 0) {
Slog.e(
OomAdjuster.TAG,
"Process.getRss returned bad value, not re-ranking: "
+ Arrays.toString(rss));
return;
}
// First element is total RSS:
// frameworks/base/core/jni/android_util_Process.cpp:1192
scoredProcessRecord.proc.mState.setCacheOomRankerRss(rss[0], nowMs);
scoredProcessRecord.proc.mProfile.setLastRss(rss[0]);
}
}
// Add scores for each of the weighted features we want to rank based on. // Add scores for each of the weighted features we want to rank based on.
if (lruWeight > 0.0f) { if (lruWeight > 0.0f) {
// This doesn't use the LRU list ordering as after the first re-ranking // This doesn't use the LRU list ordering as after the first re-ranking
@@ -305,8 +377,12 @@ public class CacheOomRanker {
addToScore(scoredProcessRecords, lruWeight); addToScore(scoredProcessRecords, lruWeight);
} }
if (rssWeight > 0.0f) { if (rssWeight > 0.0f) {
synchronized (mService.mAppProfiler.mProfilerLock) { if (useFrequentRss) {
Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, LAST_RSS_COMPARATOR); Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, RSS_COMPARATOR);
} else {
synchronized (mService.mAppProfiler.mProfilerLock) {
Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, LAST_RSS_COMPARATOR);
}
} }
addToScore(scoredProcessRecords, rssWeight); addToScore(scoredProcessRecords, rssWeight);
} }
@@ -385,6 +461,16 @@ public class CacheOomRanker {
} }
} }
private static class RssComparator implements Comparator<RankedProcessRecord> {
@Override
public int compare(RankedProcessRecord o1, RankedProcessRecord o2) {
// High RSS first to match least recently used.
return Long.compare(
o2.proc.mState.getCacheOomRankerRss(),
o1.proc.mState.getCacheOomRankerRss());
}
}
private static class LastRssComparator implements Comparator<RankedProcessRecord> { private static class LastRssComparator implements Comparator<RankedProcessRecord> {
@Override @Override
public int compare(RankedProcessRecord o1, RankedProcessRecord o2) { public int compare(RankedProcessRecord o1, RankedProcessRecord o2) {
@@ -397,4 +483,18 @@ public class CacheOomRanker {
public ProcessRecord proc; public ProcessRecord proc;
public float score; public float score;
} }
/**
* Interface for mocking {@link Process} static methods.
*/
interface ProcessDependencies {
long[] getRss(int pid);
}
private static class ProcessDependenciesImpl implements ProcessDependencies {
@Override
public long[] getRss(int pid) {
return Process.getRss(pid);
}
}
} }

View File

@@ -342,6 +342,20 @@ final class ProcessStateRecord {
@GuardedBy("mService") @GuardedBy("mService")
private int mCacheOomRankerUseCount; private int mCacheOomRankerUseCount;
/**
* Process memory usage (RSS).
*
* Periodically populated by {@code CacheOomRanker}, stored in this object to cache the values.
*/
@GuardedBy("mService")
private long mCacheOomRankerRss;
/**
* The last time, in milliseconds since boot, since {@link #mCacheOomRankerRss} was updated.
*/
@GuardedBy("mService")
private long mCacheOomRankerRssTimeMs;
/** /**
* Whether or not this process is reachable from given process. * Whether or not this process is reachable from given process.
*/ */
@@ -1150,6 +1164,21 @@ final class ProcessStateRecord {
return mLastInvisibleTime; return mLastInvisibleTime;
} }
public void setCacheOomRankerRss(long rss, long rssTimeMs) {
mCacheOomRankerRss = rss;
mCacheOomRankerRssTimeMs = rssTimeMs;
}
@GuardedBy("mService")
public long getCacheOomRankerRss() {
return mCacheOomRankerRss;
}
@GuardedBy("mService")
public long getCacheOomRankerRssTimeMs() {
return mCacheOomRankerRssTimeMs;
}
@GuardedBy({"mService", "mProcLock"}) @GuardedBy({"mService", "mProcLock"})
void dump(PrintWriter pw, String prefix, long nowUptime) { void dump(PrintWriter pw, String prefix, long nowUptime) {
if (mReportedInteraction || mFgInteractionTime != 0) { if (mReportedInteraction || mFgInteractionTime != 0) {

View File

@@ -57,6 +57,9 @@ import java.time.LocalDate;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -67,6 +70,7 @@ import java.util.concurrent.TimeUnit;
* Build/Install/Run: * Build/Install/Run:
* atest FrameworksMockingServicesTests:CacheOomRankerTest * atest FrameworksMockingServicesTests:CacheOomRankerTest
*/ */
@SuppressWarnings("GuardedBy") // No tests are concurrent, so no need to test locking.
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class CacheOomRankerTest { public class CacheOomRankerTest {
private static final Instant NOW = LocalDate.of(2021, 1, 1).atStartOfDay( private static final Instant NOW = LocalDate.of(2021, 1, 1).atStartOfDay(
@@ -91,6 +95,7 @@ public class CacheOomRankerTest {
private int mNextUid = 30000; private int mNextUid = 30000;
private int mNextPackageUid = 40000; private int mNextPackageUid = 40000;
private int mNextPackageName = 1; private int mNextPackageName = 1;
private Map<Integer, Long> mPidToRss;
private TestExecutor mExecutor = new TestExecutor(); private TestExecutor mExecutor = new TestExecutor();
private CacheOomRanker mCacheOomRanker; private CacheOomRanker mCacheOomRanker;
@@ -116,7 +121,15 @@ public class CacheOomRankerTest {
LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.removeServiceForTest(PackageManagerInternal.class);
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt); LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt);
mCacheOomRanker = new CacheOomRanker(mAms); mPidToRss = new HashMap<>();
mCacheOomRanker = new CacheOomRanker(
mAms,
pid -> {
Long rss = mPidToRss.get(pid);
assertThat(rss).isNotNull();
return new long[]{rss};
}
);
mCacheOomRanker.init(mExecutor); mCacheOomRanker.init(mExecutor);
} }
@@ -184,6 +197,8 @@ public class CacheOomRankerTest {
public void reRankLruCachedApps_lruImpactsOrdering() throws InterruptedException { public void reRankLruCachedApps_lruImpactsOrdering() throws InterruptedException {
setConfig(/* numberToReRank= */ 5, setConfig(/* numberToReRank= */ 5,
/* preserveTopNApps= */ 0, /* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 0.0f, /* usesWeight= */ 0.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */1.0f); /* lruWeight= */1.0f);
@@ -223,6 +238,8 @@ public class CacheOomRankerTest {
public void reRankLruCachedApps_rssImpactsOrdering() throws InterruptedException { public void reRankLruCachedApps_rssImpactsOrdering() throws InterruptedException {
setConfig(/* numberToReRank= */ 6, setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ 0, /* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 0.0f, /* usesWeight= */ 0.0f,
/* pssWeight= */ 1.0f, /* pssWeight= */ 1.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -260,10 +277,129 @@ public class CacheOomRankerTest {
rss16k).inOrder(); rss16k).inOrder();
} }
@Test
public void reRankLruCachedApps_rssImpactsOrdering_cachedRssValues()
throws InterruptedException {
setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 10000000,
/* usesWeight= */ 0.0f,
/* pssWeight= */ 1.0f,
/* lruWeight= */ 0.0f);
ProcessList list = new ProcessList();
ArrayList<ProcessRecord> processList = list.getLruProcessesLSP();
ProcessRecord rss10k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(40, ChronoUnit.MINUTES).toEpochMilli(), 10 * 1024L, 1000);
processList.add(rss10k);
ProcessRecord rss20k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(42, ChronoUnit.MINUTES).toEpochMilli(), 20 * 1024L, 2000);
processList.add(rss20k);
ProcessRecord rss1k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(60, ChronoUnit.MINUTES).toEpochMilli(), 1024L, 10000);
processList.add(rss1k);
ProcessRecord rss100k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(15, ChronoUnit.MINUTES).toEpochMilli(), 100 * 1024L, 10);
processList.add(rss100k);
ProcessRecord rss2k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(17, ChronoUnit.MINUTES).toEpochMilli(), 2 * 1024L, 20);
processList.add(rss2k);
ProcessRecord rss15k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 15 * 1024L, 20);
processList.add(rss15k);
// Only re-ranking 6 entries so this should stay in most recent position.
ProcessRecord rss16k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 16 * 1024L, 20);
processList.add(rss16k);
list.setLruProcessServiceStartLSP(processList.size());
mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
// First 6 ordered by largest pss, then last processes position unchanged.
assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
rss16k).inOrder();
// Clear mPidToRss so that Process.getRss calls fail.
mPidToRss.clear();
// Mix up the process list to ensure that CacheOomRanker actually re-ranks.
Collections.swap(processList, 0, 1);
mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
// Re ranking is the same.
assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
rss16k).inOrder();
}
@Test
public void reRankLruCachedApps_rssImpactsOrdering_profileRss()
throws InterruptedException {
setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ 0,
/* useFrequentRss= */ false,
/* rssUpdateRateMs= */ 10000000,
/* usesWeight= */ 0.0f,
/* pssWeight= */ 1.0f,
/* lruWeight= */ 0.0f);
ProcessList list = new ProcessList();
ArrayList<ProcessRecord> processList = list.getLruProcessesLSP();
ProcessRecord rss10k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(40, ChronoUnit.MINUTES).toEpochMilli(), 0L, 1000);
rss10k.mProfile.setLastRss(10 * 1024L);
processList.add(rss10k);
ProcessRecord rss20k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(42, ChronoUnit.MINUTES).toEpochMilli(), 0L, 2000);
rss20k.mProfile.setLastRss(20 * 1024L);
processList.add(rss20k);
ProcessRecord rss1k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(60, ChronoUnit.MINUTES).toEpochMilli(), 0L, 10000);
rss1k.mProfile.setLastRss(1024L);
processList.add(rss1k);
ProcessRecord rss100k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(15, ChronoUnit.MINUTES).toEpochMilli(), 0L, 10);
rss100k.mProfile.setLastRss(100 * 1024L);
processList.add(rss100k);
ProcessRecord rss2k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(17, ChronoUnit.MINUTES).toEpochMilli(), 0L, 20);
rss2k.mProfile.setLastRss(2 * 1024L);
processList.add(rss2k);
ProcessRecord rss15k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 15 * 1024L, 20);
rss15k.mProfile.setLastRss(15 * 1024L);
processList.add(rss15k);
// Only re-ranking 6 entries so this should stay in most recent position.
ProcessRecord rss16k = nextProcessRecord(ProcessList.UNKNOWN_ADJ,
NOW.minus(30, ChronoUnit.MINUTES).toEpochMilli(), 16 * 1024L, 20);
rss16k.mProfile.setLastRss(16 * 1024L);
processList.add(rss16k);
list.setLruProcessServiceStartLSP(processList.size());
// This should not be used, as RSS values are taken from mProfile.
mPidToRss.clear();
mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
// First 6 ordered by largest pss, then last processes position unchanged.
assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
rss16k).inOrder();
// Clear mPidToRss so that Process.getRss calls fail.
mPidToRss.clear();
// Mix up the process list to ensure that CacheOomRanker actually re-ranks.
Collections.swap(processList, 0, 1);
mCacheOomRanker.reRankLruCachedAppsLSP(processList, list.getLruProcessServiceStartLOSP());
// Re ranking is the same.
assertThat(processList).containsExactly(rss100k, rss20k, rss15k, rss10k, rss2k, rss1k,
rss16k).inOrder();
}
@Test @Test
public void reRankLruCachedApps_usesImpactsOrdering() throws InterruptedException { public void reRankLruCachedApps_usesImpactsOrdering() throws InterruptedException {
setConfig(/* numberToReRank= */ 4, setConfig(/* numberToReRank= */ 4,
/* preserveTopNApps= */ 0, /* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -302,6 +438,8 @@ public class CacheOomRankerTest {
public void reRankLruCachedApps_fewProcesses() throws InterruptedException { public void reRankLruCachedApps_fewProcesses() throws InterruptedException {
setConfig(/* numberToReRank= */ 4, setConfig(/* numberToReRank= */ 4,
/* preserveTopNApps= */ 0, /* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -339,6 +477,8 @@ public class CacheOomRankerTest {
public void reRankLruCachedApps_fewNonServiceProcesses() throws InterruptedException { public void reRankLruCachedApps_fewNonServiceProcesses() throws InterruptedException {
setConfig(/* numberToReRank= */ 4, setConfig(/* numberToReRank= */ 4,
/* preserveTopNApps= */ 0, /* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -376,6 +516,8 @@ public class CacheOomRankerTest {
public void reRankLruCachedApps_manyProcessesThenFew() throws InterruptedException { public void reRankLruCachedApps_manyProcessesThenFew() throws InterruptedException {
setConfig(/* numberToReRank= */ 6, setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ 0, /* preserveTopNApps= */ 0,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -439,6 +581,8 @@ public class CacheOomRankerTest {
public void reRankLruCachedApps_preservesTopNApps() throws InterruptedException { public void reRankLruCachedApps_preservesTopNApps() throws InterruptedException {
setConfig(/* numberToReRank= */ 6, setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ 3, /* preserveTopNApps= */ 3,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -478,6 +622,8 @@ public class CacheOomRankerTest {
throws InterruptedException { throws InterruptedException {
setConfig(/* numberToReRank= */ 6, setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ 100, /* preserveTopNApps= */ 100,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -516,6 +662,8 @@ public class CacheOomRankerTest {
throws InterruptedException { throws InterruptedException {
setConfig(/* numberToReRank= */ 6, setConfig(/* numberToReRank= */ 6,
/* preserveTopNApps= */ -100, /* preserveTopNApps= */ -100,
/* useFrequentRss= */ true,
/* rssUpdateRateMs= */ 0,
/* usesWeight= */ 1.0f, /* usesWeight= */ 1.0f,
/* pssWeight= */ 0.0f, /* pssWeight= */ 0.0f,
/* lruWeight= */ 0.0f); /* lruWeight= */ 0.0f);
@@ -550,8 +698,8 @@ public class CacheOomRankerTest {
used200).inOrder(); used200).inOrder();
} }
private void setConfig(int numberToReRank, int preserveTopNApps, float usesWeight, private void setConfig(int numberToReRank, int preserveTopNApps, boolean useFrequentRss,
float pssWeight, float lruWeight) long rssUpdateRateMs, float usesWeight, float pssWeight, float lruWeight)
throws InterruptedException { throws InterruptedException {
mExecutor.init(4); mExecutor.init(4);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -562,6 +710,14 @@ public class CacheOomRankerTest {
CacheOomRanker.KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS, CacheOomRanker.KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS,
Integer.toString(preserveTopNApps), Integer.toString(preserveTopNApps),
false); false);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
CacheOomRanker.KEY_OOM_RE_RANKING_USE_FREQUENT_RSS,
Boolean.toString(useFrequentRss),
false);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
CacheOomRanker.KEY_OOM_RE_RANKING_RSS_UPDATE_RATE_MS,
Long.toString(rssUpdateRateMs),
false);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
CacheOomRanker.KEY_OOM_RE_RANKING_LRU_WEIGHT, CacheOomRanker.KEY_OOM_RE_RANKING_LRU_WEIGHT,
Float.toString(lruWeight), Float.toString(lruWeight),
@@ -576,6 +732,8 @@ public class CacheOomRankerTest {
false); false);
mExecutor.waitForLatch(); mExecutor.waitForLatch();
assertThat(mCacheOomRanker.getNumberToReRank()).isEqualTo(numberToReRank); assertThat(mCacheOomRanker.getNumberToReRank()).isEqualTo(numberToReRank);
assertThat(mCacheOomRanker.mUseFrequentRss).isEqualTo(useFrequentRss);
assertThat(mCacheOomRanker.mRssUpdateRateMs).isEqualTo(rssUpdateRateMs);
assertThat(mCacheOomRanker.mRssWeight).isEqualTo(pssWeight); assertThat(mCacheOomRanker.mRssWeight).isEqualTo(pssWeight);
assertThat(mCacheOomRanker.mUsesWeight).isEqualTo(usesWeight); assertThat(mCacheOomRanker.mUsesWeight).isEqualTo(usesWeight);
assertThat(mCacheOomRanker.mLruWeight).isEqualTo(lruWeight); assertThat(mCacheOomRanker.mLruWeight).isEqualTo(lruWeight);
@@ -592,7 +750,7 @@ public class CacheOomRankerTest {
app.mState.setSetProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE); app.mState.setSetProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
app.mState.setCurAdj(setAdj); app.mState.setCurAdj(setAdj);
app.setLastActivityTime(lastActivityTime); app.setLastActivityTime(lastActivityTime);
app.mProfile.setLastRss(lastRss); mPidToRss.put(app.getPid(), lastRss);
app.mState.setCached(false); app.mState.setCached(false);
for (int i = 0; i < wentToForegroundCount; ++i) { for (int i = 0; i < wentToForegroundCount; ++i) {
app.mState.setSetProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); app.mState.setSetProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);