Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bd226e3 authored by Misha Wagner's avatar Misha Wagner
Browse files

Use Process.getRss instead of mProfile.getLastRss in CacheOomRanker.

RSS values are cached in ProcessStateRecord, and repopulated when they
are >10s old.

mProfile.getLastRss values can be 15s-2h stale, which is why we're using
this implementation. My understanding is that the best solution would be
to populate mProfile.getLastRss more often - but it is currently
populated alongside PSS, which is more expensive to calculate.
Therefore, rather than the more complex change of splitting up PSS & RSS
collection, we opt for this simple (if not optimal) approach as
CacheOomRanker is still experimental. Upon successful launch, we can
revisit this.

When logging the duration of CacheOomRanker calculations, we saw no
significant increase in computation time with this change. If we turn
off caching RSS values, we see a 10x increase in computation time.

Test: atest CacheOomRankerTest
Bug: 196031723
Change-Id: I8e80db2aab338df07f07842131a9d4b55bebd054
parent a5294fb6
Loading
Loading
Loading
Loading
+101 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.am;

import android.os.Process;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.Slog;

@@ -46,6 +48,14 @@ public class CacheOomRanker {
    @VisibleForTesting
    static final int DEFAULT_PRESERVE_TOP_N_APPS = 3;
    @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";
    @VisibleForTesting
    static final float DEFAULT_OOM_RE_RANKING_LRU_WEIGHT = 0.35f;
@@ -62,6 +72,8 @@ public class CacheOomRanker {
            new ScoreComparator();
    private static final Comparator<RankedProcessRecord> CACHE_USE_COMPARATOR =
            new CacheUseComparator();
    private static final Comparator<RankedProcessRecord> RSS_COMPARATOR =
            new RssComparator();
    private static final Comparator<RankedProcessRecord> LAST_RSS_COMPARATOR =
            new LastRssComparator();
    private static final Comparator<RankedProcessRecord> LAST_ACTIVITY_TIME_COMPARATOR =
@@ -70,6 +82,7 @@ public class CacheOomRanker {
    private final Object mPhenotypeFlagLock = new Object();

    private final ActivityManagerService mService;
    private final ProcessDependencies mProcessDependencies;
    private final ActivityManagerGlobalLock mProcLock;
    private final Object mProfilerLock;

@@ -78,6 +91,12 @@ public class CacheOomRanker {
    @GuardedBy("mPhenotypeFlagLock")
    @VisibleForTesting
    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.
    @GuardedBy("mPhenotypeFlagLock")
    @VisibleForTesting
@@ -110,6 +129,10 @@ public class CacheOomRanker {
                                updateNumberToReRank();
                            } else if (KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS.equals(name)) {
                                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)) {
                                updateLruWeight();
                            } else if (KEY_OOM_RE_RANKING_USES_WEIGHT.equals(name)) {
@@ -123,9 +146,15 @@ public class CacheOomRanker {
            };

    CacheOomRanker(final ActivityManagerService service) {
        this(service, new ProcessDependenciesImpl());
    }

    @VisibleForTesting
    CacheOomRanker(final ActivityManagerService service, ProcessDependencies processDependencies) {
        mService = service;
        mProcLock = service.mProcLock;
        mProfilerLock = service.mAppProfiler.mProfilerLock;
        mProcessDependencies = processDependencies;
    }

    /** Load settings from device config and register a listener for changes. */
@@ -189,6 +218,18 @@ public class CacheOomRanker {
        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")
    private void updateLruWeight() {
        mLruWeight = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -244,6 +285,8 @@ public class CacheOomRanker {
        float usesWeight;
        float rssWeight;
        int preserveTopNApps;
        boolean useFrequentRss;
        long rssUpdateRateMs;
        int[] lruPositions;
        RankedProcessRecord[] scoredProcessRecords;

@@ -252,6 +295,8 @@ public class CacheOomRanker {
            usesWeight = mUsesWeight;
            rssWeight = mRssWeight;
            preserveTopNApps = mPreserveTopNApps;
            useFrequentRss = mUseFrequentRss;
            rssUpdateRateMs = mRssUpdateRateMs;
            lruPositions = mLruPositions;
            scoredProcessRecords = mScoredProcessRecords;
        }
@@ -296,6 +341,32 @@ 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);
            }
        }

        // Add scores for each of the weighted features we want to rank based on.
        if (lruWeight > 0.0f) {
            // This doesn't use the LRU list ordering as after the first re-ranking
@@ -305,9 +376,13 @@ public class CacheOomRanker {
            addToScore(scoredProcessRecords, lruWeight);
        }
        if (rssWeight > 0.0f) {
            if (useFrequentRss) {
                Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, RSS_COMPARATOR);
            } else {
                synchronized (mService.mAppProfiler.mProfilerLock) {
                    Arrays.sort(scoredProcessRecords, 0, numProcessesReRanked, LAST_RSS_COMPARATOR);
                }
            }
            addToScore(scoredProcessRecords, rssWeight);
        }
        if (usesWeight > 0.0f) {
@@ -385,6 +460,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> {
        @Override
        public int compare(RankedProcessRecord o1, RankedProcessRecord o2) {
@@ -397,4 +482,18 @@ public class CacheOomRanker {
        public ProcessRecord proc;
        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);
        }
    }
}
+29 −0
Original line number Diff line number Diff line
@@ -359,6 +359,20 @@ final class ProcessStateRecord {
    @GuardedBy("mService")
    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.
     */
@@ -1266,6 +1280,21 @@ final class ProcessStateRecord {
        return mLastCanKillOnBgRestrictedAndIdleTime;
    }

    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"})
    void dump(PrintWriter pw, String prefix, long nowUptime) {
        if (mReportedInteraction || mFgInteractionTime != 0) {
+162 −4
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
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.Executor;
import java.util.concurrent.TimeUnit;
@@ -67,6 +70,7 @@ import java.util.concurrent.TimeUnit;
 * Build/Install/Run:
 * atest FrameworksMockingServicesTests:CacheOomRankerTest
 */
@SuppressWarnings("GuardedBy") // No tests are concurrent, so no need to test locking.
@RunWith(MockitoJUnitRunner.class)
public class CacheOomRankerTest {
    private static final Instant NOW = LocalDate.of(2021, 1, 1).atStartOfDay(
@@ -91,6 +95,7 @@ public class CacheOomRankerTest {
    private int mNextUid = 30000;
    private int mNextPackageUid = 40000;
    private int mNextPackageName = 1;
    private Map<Integer, Long> mPidToRss;

    private TestExecutor mExecutor = new TestExecutor();
    private CacheOomRanker mCacheOomRanker;
@@ -116,7 +121,15 @@ public class CacheOomRankerTest {
        LocalServices.removeServiceForTest(PackageManagerInternal.class);
        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);
    }

@@ -184,6 +197,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_lruImpactsOrdering() throws InterruptedException {
        setConfig(/* numberToReRank= */ 5,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 0.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */1.0f);
@@ -223,6 +238,52 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_rssImpactsOrdering() throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* 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();
    }

    @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);
@@ -254,16 +315,91 @@ public class CacheOomRankerTest {
        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
    public void reRankLruCachedApps_usesImpactsOrdering() throws InterruptedException {
        setConfig(/* numberToReRank= */ 4,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -302,6 +438,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_fewProcesses() throws InterruptedException {
        setConfig(/* numberToReRank= */ 4,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -339,6 +477,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_fewNonServiceProcesses() throws InterruptedException {
        setConfig(/* numberToReRank= */ 4,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -376,6 +516,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_manyProcessesThenFew() throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 0,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -439,6 +581,8 @@ public class CacheOomRankerTest {
    public void reRankLruCachedApps_preservesTopNApps() throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 3,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -478,6 +622,8 @@ public class CacheOomRankerTest {
            throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ 100,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -516,6 +662,8 @@ public class CacheOomRankerTest {
            throws InterruptedException {
        setConfig(/* numberToReRank= */ 6,
                /* preserveTopNApps= */ -100,
                /* useFrequentRss= */ true,
                /* rssUpdateRateMs= */ 0,
                /* usesWeight= */ 1.0f,
                /* pssWeight= */ 0.0f,
                /* lruWeight= */ 0.0f);
@@ -550,8 +698,8 @@ public class CacheOomRankerTest {
                used200).inOrder();
    }

    private void setConfig(int numberToReRank, int preserveTopNApps, float usesWeight,
            float pssWeight, float lruWeight)
    private void setConfig(int numberToReRank, int preserveTopNApps, boolean useFrequentRss,
            long rssUpdateRateMs, float usesWeight, float pssWeight, float lruWeight)
            throws InterruptedException {
        mExecutor.init(4);
        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -562,6 +710,14 @@ public class CacheOomRankerTest {
                CacheOomRanker.KEY_OOM_RE_RANKING_PRESERVE_TOP_N_APPS,
                Integer.toString(preserveTopNApps),
                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,
                CacheOomRanker.KEY_OOM_RE_RANKING_LRU_WEIGHT,
                Float.toString(lruWeight),
@@ -576,6 +732,8 @@ public class CacheOomRankerTest {
                false);
        mExecutor.waitForLatch();
        assertThat(mCacheOomRanker.getNumberToReRank()).isEqualTo(numberToReRank);
        assertThat(mCacheOomRanker.mUseFrequentRss).isEqualTo(useFrequentRss);
        assertThat(mCacheOomRanker.mRssUpdateRateMs).isEqualTo(rssUpdateRateMs);
        assertThat(mCacheOomRanker.mRssWeight).isEqualTo(pssWeight);
        assertThat(mCacheOomRanker.mUsesWeight).isEqualTo(usesWeight);
        assertThat(mCacheOomRanker.mLruWeight).isEqualTo(lruWeight);
@@ -592,7 +750,7 @@ public class CacheOomRankerTest {
        app.mState.setSetProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
        app.mState.setCurAdj(setAdj);
        app.setLastActivityTime(lastActivityTime);
        app.mProfile.setLastRss(lastRss);
        mPidToRss.put(app.getPid(), lastRss);
        app.mState.setCached(false);
        for (int i = 0; i < wentToForegroundCount; ++i) {
            app.mState.setSetProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);