Ensure ThreadDeathWatcher and GlobalEventExecutor will not cause classloader leaks.

Motivation:

ThreadDeathWatcher and GlobalEventExecutor may create and start a new thread from various other threads and so inherit the classloader. We need to ensure we not inherit to allow recycling the classloader.

Modifications:

Use Thread.setContextClassLoader(null) to ensure we not hold a strong reference to the classloader and so not leak it.

Result:

Fixes [#7290].
This commit is contained in:
Norman Maurer 2017-12-11 15:18:34 +01:00
parent b2bc6407ab
commit 63bae0956a
2 changed files with 14 additions and 0 deletions

View File

@ -104,6 +104,13 @@ public final class ThreadDeathWatcher {
if (started.compareAndSet(false, true)) {
Thread watcherThread = threadFactory.newThread(watcher);
// Set to null to ensure we not create classloader leaks by holds a strong reference to the inherited
// classloader.
// See:
// - https://github.com/netty/netty/issues/7290
// - https://bugs.openjdk.java.net/browse/JDK-7008595
watcherThread.setContextClassLoader(null);
watcherThread.start();
ThreadDeathWatcher.watcherThread = watcherThread;
}

View File

@ -215,6 +215,13 @@ public final class GlobalEventExecutor extends AbstractScheduledEventExecutor {
private void startThread() {
if (started.compareAndSet(false, true)) {
Thread t = threadFactory.newThread(taskRunner);
// Set to null to ensure we not create classloader leaks by holds a strong reference to the inherited
// classloader.
// See:
// - https://github.com/netty/netty/issues/7290
// - https://bugs.openjdk.java.net/browse/JDK-7008595
t.setContextClassLoader(null);
// Set the thread before starting it as otherwise inEventLoop() may return false and so produce
// an assert error.
// See https://github.com/netty/netty/issues/4357