diff options
| author | 2021-09-03 18:05:44 +0200 | |
|---|---|---|
| committer | 2021-09-23 14:48:52 +0000 | |
| commit | 7d2da2c2d23301c2bc9a0db8fcc7d28b6e91a747 (patch) | |
| tree | 0fabaa6d5868d1ae0312089f77601ba44922aa45 | |
| parent | 938b7d01f5137ca9d320b13032c62cf29b22b01b (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.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 11 |
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 |