diff options
| author | 2020-04-28 15:31:42 -0700 | |
|---|---|---|
| committer | 2020-05-13 11:15:14 -0700 | |
| commit | 8c239da8d54bc2ac93fe666a7ca7825f0e82b923 (patch) | |
| tree | 7d4a8b48b46177d41dd1705db9f96da9a5ab25eb | |
| parent | 1daf6ea6a39c1bd56a5792ab6cd8469aba0a441b (diff) | |
Maintain global list of caches; purge on low memory
Bug: 140788621
Test: m
Merged-In: I3ba88e0a6f6c0f26465903988e7432156bd5be20
Change-Id: I3ba88e0a6f6c0f26465903988e7432156bd5be20
(cherry picked from commit 22c2ddb201e52e54d82d2a8dba77c19d74e654ba)
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 6 | ||||
| -rw-r--r-- | core/java/android/app/PropertyInvalidatedCache.java | 25 |
2 files changed, 31 insertions, 0 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index eea1d69b6326..c6e2d5290d2e 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -6202,6 +6202,12 @@ public final class ActivityThread extends ClientTransactionHandler { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory"); if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); + if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { + for (PropertyInvalidatedCache pic : PropertyInvalidatedCache.getActiveCaches()) { + pic.clear(); + } + } + ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); final int N = callbacks.size(); diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java index 3110e18985b0..58705434f774 100644 --- a/core/java/android/app/PropertyInvalidatedCache.java +++ b/core/java/android/app/PropertyInvalidatedCache.java @@ -27,11 +27,13 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; import java.util.Random; +import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicLong; /** @@ -197,6 +199,14 @@ public abstract class PropertyInvalidatedCache<Query, Result> { @GuardedBy("sCorkLock") private static final HashMap<String, Integer> sCorks = new HashMap<>(); + /** + * Weakly references all cache objects in the current process, allowing us to iterate over + * them all for purposes like issuing debug dumps and reacting to memory pressure. + */ + @GuardedBy("sCorkLock") + private static final WeakHashMap<PropertyInvalidatedCache, Void> sCaches = + new WeakHashMap<>(); + private final Object mLock = new Object(); /** @@ -241,6 +251,9 @@ public abstract class PropertyInvalidatedCache<Query, Result> { return size() > maxEntries; } }; + synchronized (sCorkLock) { + sCaches.put(this, null); + } } /** @@ -248,6 +261,9 @@ public abstract class PropertyInvalidatedCache<Query, Result> { */ public final void clear() { synchronized (mLock) { + if (DEBUG) { + Log.d(TAG, "clearing cache for " + mPropertyName); + } mCache.clear(); } } @@ -710,4 +726,13 @@ public abstract class PropertyInvalidatedCache<Query, Result> { Log.d(TAG, "disabling all caches in the process"); sEnabled = false; } + + /** + * Return a list of caches alive at the current time. + */ + public static ArrayList<PropertyInvalidatedCache> getActiveCaches() { + synchronized (sCorkLock) { + return new ArrayList<PropertyInvalidatedCache>(sCaches.keySet()); + } + } } |