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
(20k currently). 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.

Bug: 198340142
Test: Manual
Change-Id: I75c7ea4f7aa4a5d448f610014770f1b9788cfb5b
This commit is contained in:
Martijn Coenen
2021-09-03 18:05:44 +02:00
parent 291d2b44da
commit 858b2926ff

View File

@@ -7810,6 +7810,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