From d288a266723e18d846ea1215919f7a377504225b Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Fri, 10 Jul 2015 13:44:42 -0700 Subject: [PATCH] Change conditionallyCheckInstanceCounts to use countInstancesOfClasses countInstancesOfClasses allows passing multiple classes unlike countInstanceOfClass. This provides a speedup since we dont traverse the heap multiple times. Changed ActivityThread.dumpMemInfo to do a GC since countInstancesOfClass no longer does GC before counting. https://code.google.com/p/android/issues/detail?id=177552 Change-Id: Ia85684f40cf59a52aa71a8479c711a994651209b --- core/java/android/app/ActivityThread.java | 2 +- core/java/android/os/StrictMode.java | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 9449eff1f40b0..0d71ea33eb840 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -973,7 +973,7 @@ public final class ActivityThread { long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Runtime runtime = Runtime.getRuntime(); - + runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects. long dalvikMax = runtime.totalMemory() / 1024; long dalvikFree = runtime.freeMemory() / 1024; long dalvikAllocated = dalvikMax - dalvikFree; diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 50187111bde58..44f4ab1c1bb92 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -1520,7 +1520,8 @@ public final class StrictMode { */ public static void conditionallyCheckInstanceCounts() { VmPolicy policy = getVmPolicy(); - if (policy.classInstanceLimit.size() == 0) { + int policySize = policy.classInstanceLimit.size(); + if (policySize == 0) { return; } @@ -1529,15 +1530,17 @@ public final class StrictMode { System.gc(); // Note: classInstanceLimit is immutable, so this is lock-free - for (Map.Entry entry : policy.classInstanceLimit.entrySet()) { - Class klass = entry.getKey(); - int limit = entry.getValue(); - long instances = VMDebug.countInstancesOfClass(klass, false); - if (instances <= limit) { - continue; + // Create the classes array. + Class[] classes = policy.classInstanceLimit.keySet().toArray(new Class[policySize]); + long[] instanceCounts = VMDebug.countInstancesOfClasses(classes, false); + for (int i = 0; i < classes.length; ++i) { + Class klass = classes[i]; + int limit = policy.classInstanceLimit.get(klass); + long instances = instanceCounts[i]; + if (instances > limit) { + Throwable tr = new InstanceCountViolation(klass, instances, limit); + onVmPolicyViolation(tr.getMessage(), tr); } - Throwable tr = new InstanceCountViolation(klass, instances, limit); - onVmPolicyViolation(tr.getMessage(), tr); } }