detect and ignore idle ForkJoin common pool thread

This commit is contained in:
Dana Dahlstrom
2017-06-07 13:26:25 +03:00
committed by Alexey Kudravtsev
parent c9773ffcd1
commit 299ad1ce27
@@ -38,6 +38,7 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.TimeUnit;
/**
@@ -151,6 +152,10 @@ public class ThreadTracker {
continue;
}
if (isIdleCommonPoolThread(thread, stackTrace)) {
continue;
}
@SuppressWarnings("NonConstantStringShouldBeStringBuffer")
String trace = "Thread leaked: " + thread + "; " + thread.getState() + " (" + thread.isAlive() + ")\n--- its stacktrace:\n";
for (final StackTraceElement stackTraceElement : stackTrace) {
@@ -171,7 +176,7 @@ public class ThreadTracker {
}
// true if somebody started new thread via "executeInPooledThread()" and then the thread is waiting for next task
private static boolean isIdleApplicationPoolThread(Thread thread, StackTraceElement[] stackTrace) {
private static boolean isIdleApplicationPoolThread(@NotNull Thread thread, @NotNull StackTraceElement[] stackTrace) {
if (!isWellKnownOffender(thread)) return false;
boolean insideTPEGetTask = Arrays.stream(stackTrace)
.anyMatch(element -> element.getMethodName().equals("getTask")
@@ -180,6 +185,16 @@ public class ThreadTracker {
return insideTPEGetTask;
}
private static boolean isIdleCommonPoolThread(@NotNull Thread thread, @NotNull StackTraceElement[] stackTrace) {
if (!ForkJoinWorkerThread.class.isAssignableFrom(thread.getClass())) {
return false;
}
boolean insideAwaitWork = Arrays.stream(stackTrace)
.anyMatch(element -> element.getMethodName().equals("awaitWork")
&& element.getClassName().equals("java.util.concurrent.ForkJoinPool"));
return insideAwaitWork;
}
public static void awaitJDIThreadsTermination(int timeout, @NotNull TimeUnit unit) {
awaitThreadTerminationWithParentParentGroup("JDI main", timeout, unit);
}