summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Daniel Colascione <dancol@google.com> 2020-04-28 15:31:42 -0700
committer Collin Fijalkovich <cfijalkovich@google.com> 2020-05-13 11:15:14 -0700
commit8c239da8d54bc2ac93fe666a7ca7825f0e82b923 (patch)
tree7d4a8b48b46177d41dd1705db9f96da9a5ab25eb
parent1daf6ea6a39c1bd56a5792ab6cd8469aba0a441b (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.java6
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java25
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());
+ }
+ }
}