summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Martijn Coenen <maco@google.com> 2021-09-03 18:05:44 +0200
committer Martijn Coenen <maco@google.com> 2021-09-23 14:48:52 +0000
commit7d2da2c2d23301c2bc9a0db8fcc7d28b6e91a747 (patch)
tree0fabaa6d5868d1ae0312089f77601ba44922aa45
parent938b7d01f5137ca9d320b13032c62cf29b22b01b (diff)
Run a GC after killing a UID due to binder proxy limit.
After we hit the per-UID proxy limit and kill the originating process, there's actually no guarantee that the proxies to the (now dead) processes are cleaned up immediately; if the processes get restarted and start accumulating proxies again, we may go over the global proxy limit (25k with this CL). Do a GC to make sure we clean them up. Note that the GC here might not actually clean up all the proxies, because the binder reference decrements will come in asynchronously; but if new processes belonging to the UID keep adding proxies, we will get another callback here, and run the GC again - this time cleaning up the old proxies. Because of this potential delay, an app may temporarily have many more outstanding proxies than the high watermark, so also increase the global proxy limit to 25k proxies. Bug: 198340142 Test: Manual Change-Id: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b Merged-In: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b
-rw-r--r--core/java/android/os/BinderProxy.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java11
2 files changed, 12 insertions, 1 deletions
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 3d466a0bf007..c6466235e5d1 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -74,7 +74,7 @@ public final class BinderProxy implements IBinder {
private static final int MAIN_INDEX_SIZE = 1 << LOG_MAIN_INDEX_SIZE;
private static final int MAIN_INDEX_MASK = MAIN_INDEX_SIZE - 1;
// Debuggable builds will throw an AssertionError if the number of map entries exceeds:
- private static final int CRASH_AT_SIZE = 20_000;
+ private static final int CRASH_AT_SIZE = 25_000;
/**
* We next warn when we exceed this bucket size.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8f2afdba5251..c78d5d538f8d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7736,6 +7736,17 @@ public class ActivityManagerService extends IActivityManager.Stub
} else {
killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
"Too many Binders sent to SYSTEM");
+ // We need to run a GC here, because killing the processes involved
+ // actually isn't guaranteed to free up the proxies; in fact, if the
+ // GC doesn't run for a long time, we may even exceed the global
+ // proxy limit for a process (20000), resulting in system_server itself
+ // being killed.
+ // Note that the GC here might not actually clean up all the proxies,
+ // because the binder reference decrements will come in asynchronously;
+ // but if new processes belonging to the UID keep adding proxies, we
+ // will get another callback here, and run the GC again - this time
+ // cleaning up the old proxies.
+ VMRuntime.getRuntime().requestConcurrentGC();
}
}, mHandler);
t.traceEnd(); // setBinderProxies