diff --git a/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java b/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java index 4fd6258a9bdd..38a6fe56bfa5 100644 --- a/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java +++ b/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java @@ -27,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; +import java.lang.management.ThreadInfo; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; @@ -44,7 +45,7 @@ public final class PerformanceWatcher implements Disposable { private static final int TOLERABLE_LATENCY = 100; private static final String THREAD_DUMPS_PREFIX = "threadDumps-"; private ScheduledFuture myThread; - private ScheduledFuture myDumpTask; + private SamplingTask myDumpTask; private final File myLogDir = new File(PathManager.getLogPath()); private List myStacktraceCommonPart; @@ -238,7 +239,12 @@ public final class PerformanceWatcher implements Disposable { myFreezeStart = start; getPublisher().uiFreezeStarted(); stopDumping(); - myDumpTask = myExecutor.scheduleWithFixedDelay(this::dumpThreads, 0, getDumpInterval(), TimeUnit.MILLISECONDS); + myDumpTask = new SamplingTask(getDumpInterval(), getMaxDumpDuration()) { + @Override + protected void dumpedThreads(ThreadInfo[] infos) { + dumpThreads(getFreezeFolderName(myFreezeStart) + "/", false, infos); + } + }; } @NotNull @@ -256,7 +262,7 @@ public final class PerformanceWatcher implements Disposable { private void stopDumping() { if (myDumpTask != null) { - myDumpTask.cancel(false); + myDumpTask.cancel(); } } @@ -322,6 +328,11 @@ public final class PerformanceWatcher implements Disposable { @Nullable public File dumpThreads(@NotNull String pathPrefix, boolean millis) { + return dumpThreads(pathPrefix, millis, ThreadDumper.getThreadInfos()); + } + + @Nullable + private File dumpThreads(@NotNull String pathPrefix, boolean millis, ThreadInfo[] threadInfos) { if (!shouldWatch()) return null; if (!pathPrefix.contains("/")) { @@ -342,7 +353,7 @@ public final class PerformanceWatcher implements Disposable { checkMemoryUsage(file); - ThreadDump threadDump = ThreadDumper.getThreadDumpInfo(ManagementFactory.getThreadMXBean()); + ThreadDump threadDump = ThreadDumper.getThreadDumpInfo(threadInfos); try { FileUtil.writeToFile(file, threadDump.getRawDump()); StackTraceElement[] edtStack = threadDump.getEDTStackTrace(); diff --git a/platform/core-impl/src/com/intellij/diagnostic/SamplingTask.java b/platform/core-impl/src/com/intellij/diagnostic/SamplingTask.java index a0b51189ecf3..722e3f0d1be9 100644 --- a/platform/core-impl/src/com/intellij/diagnostic/SamplingTask.java +++ b/platform/core-impl/src/com/intellij/diagnostic/SamplingTask.java @@ -45,9 +45,13 @@ public class SamplingTask { if (myThreadInfos.size() >= myMaxDumps) { cancel(); } + dumpedThreads(infos); } } + protected void dumpedThreads(ThreadInfo[] infos) { + } + private static long currentGcTime() { return GC_MX_BEANS.stream().mapToLong(GarbageCollectorMXBean::getCollectionTime).sum(); } diff --git a/platform/util/src/com/intellij/diagnostic/ThreadDumper.java b/platform/util/src/com/intellij/diagnostic/ThreadDumper.java index 91aeac627fb7..5f1277e2e4f7 100644 --- a/platform/util/src/com/intellij/diagnostic/ThreadDumper.java +++ b/platform/util/src/com/intellij/diagnostic/ThreadDumper.java @@ -47,14 +47,13 @@ public class ThreadDumper { @NotNull public static ThreadInfo[] getThreadInfos() { - ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - return sort(threadMXBean.dumpAllThreads(false, false)); + return getThreadInfos(ManagementFactory.getThreadMXBean(), true); } @NotNull - public static ThreadDump getThreadDumpInfo(@NotNull final ThreadMXBean threadMXBean) { + public static ThreadDump getThreadDumpInfo(ThreadInfo[] threadInfos) { + sort(threadInfos); StringWriter writer = new StringWriter(); - ThreadInfo[] threadInfos = getThreadInfos(threadMXBean, true); StackTraceElement[] edtStack = dumpThreadInfos(threadInfos, writer); return new ThreadDump(writer.toString(), edtStack, threadInfos); }