Merge "Binder: Log a histogram of binder proxies to logcat on death"

am: 4b7abe301c

Change-Id: I8f29f452707bb38799877f23d0d04152619c81cb
This commit is contained in:
Andreas Gampe
2017-12-27 20:18:25 +00:00
committed by android-build-merger

View File

@@ -35,6 +35,9 @@ import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* Base class for a remotable object, the core part of a lightweight
@@ -888,17 +891,62 @@ final class BinderProxy implements IBinder {
keyArray[size] = key;
}
if (size >= mWarnBucketSize) {
final int total_size = size();
final int totalSize = size();
Log.v(Binder.TAG, "BinderProxy map growth! bucket size = " + size
+ " total = " + total_size);
+ " total = " + totalSize);
mWarnBucketSize += WARN_INCREMENT;
if (Build.IS_DEBUGGABLE && total_size > CRASH_AT_SIZE) {
throw new AssertionError("Binder ProxyMap has too many entries. "
+ "BinderProxy leak?");
if (Build.IS_DEBUGGABLE && totalSize > CRASH_AT_SIZE) {
diagnosticCrash();
}
}
}
/**
* Dump a histogram to the logcat, then throw an assertion error. Used to diagnose
* abnormally large proxy maps.
*/
private void diagnosticCrash() {
Map<String, Integer> counts = new HashMap<>();
for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
if (a != null) {
for (WeakReference<BinderProxy> weakRef : a) {
BinderProxy bp = weakRef.get();
String key;
if (bp == null) {
key = "<cleared weak-ref>";
} else {
try {
key = bp.getInterfaceDescriptor();
} catch (Throwable t) {
key = "<exception during getDescriptor>";
}
}
Integer i = counts.get(key);
if (i == null) {
counts.put(key, 1);
} else {
counts.put(key, i + 1);
}
}
}
}
Map.Entry<String, Integer>[] sorted = counts.entrySet().toArray(
new Map.Entry[counts.size()]);
Arrays.sort(sorted, (Map.Entry<String, Integer> a, Map.Entry<String, Integer> b)
-> b.getValue().compareTo(a.getValue()));
Log.v(Binder.TAG, "BinderProxy descriptor histogram (top ten):");
int printLength = Math.min(10, sorted.length);
for (int i = 0; i < printLength; i++) {
Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i].getKey() + " x"
+ sorted[i].getValue());
}
// Now throw an assertion.
final int totalSize = size();
throw new AssertionError("Binder ProxyMap has too many entries: " + totalSize
+ ". BinderProxy leak?");
}
// Corresponding ArrayLists in the following two arrays always have the same size.
// They contain no empty entries. However WeakReferences in the values ArrayLists
// may have been cleared.