Merge "Only count uncleared ProxyMap refs when deciding to crash"

am: 90027eb1c2

Change-Id: I56471aa9ac0b93e3280b48fed3b29ad2b743cf39
This commit is contained in:
Hans Boehm
2018-01-09 04:46:32 +00:00
committed by android-build-merger

View File

@@ -792,7 +792,7 @@ final class BinderProxy implements IBinder {
/**
* Return the total number of pairs in the map.
*/
int size() {
private int size() {
int size = 0;
for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
if (a != null) {
@@ -802,6 +802,24 @@ final class BinderProxy implements IBinder {
return size;
}
/**
* Return the total number of pairs in the map containing values that have
* not been cleared. More expensive than the above size function.
*/
private int unclearedSize() {
int size = 0;
for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
if (a != null) {
for (WeakReference<BinderProxy> ref : a) {
if (ref.get() != null) {
++size;
}
}
}
}
return size;
}
/**
* Remove ith entry from the hash bucket indicated by hash.
*/
@@ -895,17 +913,31 @@ final class BinderProxy implements IBinder {
Log.v(Binder.TAG, "BinderProxy map growth! bucket size = " + size
+ " total = " + totalSize);
mWarnBucketSize += WARN_INCREMENT;
if (Build.IS_DEBUGGABLE && totalSize > CRASH_AT_SIZE) {
diagnosticCrash();
if (Build.IS_DEBUGGABLE && totalSize >= CRASH_AT_SIZE) {
// Use the number of uncleared entries to determine whether we should
// really report a histogram and crash. We don't want to fundamentally
// change behavior for a debuggable process, so we GC only if we are
// about to crash.
final int totalUnclearedSize = unclearedSize();
if (totalUnclearedSize >= CRASH_AT_SIZE) {
dumpProxyInterfaceCounts();
Runtime.getRuntime().gc();
throw new AssertionError("Binder ProxyMap has too many entries: "
+ totalSize + " (total), " + totalUnclearedSize + " (uncleared), "
+ unclearedSize() + " (uncleared after GC). BinderProxy leak?");
} else if (totalSize > 3 * totalUnclearedSize / 2) {
Log.v(Binder.TAG, "BinderProxy map has many cleared entries: "
+ (totalSize - totalUnclearedSize) + " of " + totalSize
+ " are cleared");
}
}
}
}
/**
* Dump a histogram to the logcat, then throw an assertion error. Used to diagnose
* abnormally large proxy maps.
* Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps.
*/
private void diagnosticCrash() {
private void dumpProxyInterfaceCounts() {
Map<String, Integer> counts = new HashMap<>();
for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) {
if (a != null) {
@@ -940,11 +972,6 @@ final class BinderProxy implements IBinder {
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.