Still researching the source of these leaks.
The way the leak happens is, a java.util.concurrent.ThreadPoolExecutor is constructed from an unprivileged context. The pool starts up and threads are created without a problem, however, the thread pool is never shut down. The finalizer runs but since it tries to shut down the pool with an access control context that was captured during construction, it fails because the context did not have the modifyThread RuntimePermission, and the thread pool never shuts down.
We need to identify the points where TPEs are being constructed without controlled privileges.