Skip to content

Commit

Permalink
8315702: jcmd Thread.dump_to_file slow with millions of virtual threads
Browse files Browse the repository at this point in the history
Reviewed-by: mchung, amenkov, jpai
  • Loading branch information
Alan Bateman committed Sep 8, 2023
1 parent 3a00ec8 commit 3c258ac
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/
package jdk.internal.vm;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -110,7 +111,8 @@ private static byte[] dumpThreadsToFile(String file, boolean okayToOverwrite, bo
: new OpenOption[] { StandardOpenOption.CREATE_NEW };
String reply;
try (OutputStream out = Files.newOutputStream(path, options);
PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8)) {
BufferedOutputStream bos = new BufferedOutputStream(out);
PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8)) {
if (json) {
dumpThreadsToJson(ps);
} else {
Expand All @@ -132,11 +134,12 @@ private static byte[] dumpThreadsToFile(String file, boolean okayToOverwrite, bo
* This method is invoked by HotSpotDiagnosticMXBean.dumpThreads.
*/
public static void dumpThreads(OutputStream out) {
PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8);
BufferedOutputStream bos = new BufferedOutputStream(out);
PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8);
try {
dumpThreads(ps);
} finally {
ps.flush();
ps.flush(); // flushes underlying stream
}
}

Expand All @@ -158,9 +161,10 @@ private static void dumpThreads(ThreadContainer container, PrintStream ps) {

private static void dumpThread(Thread thread, PrintStream ps) {
String suffix = thread.isVirtual() ? " virtual" : "";
ps.format("#%d \"%s\"%s%n", thread.threadId(), thread.getName(), suffix);
ps.println("#" + thread.threadId() + " \"" + thread.getName() + "\"" + suffix);
for (StackTraceElement ste : thread.getStackTrace()) {
ps.format(" %s%n", ste);
ps.print(" ");
ps.println(ste);
}
ps.println();
}
Expand All @@ -171,11 +175,12 @@ private static void dumpThread(Thread thread, PrintStream ps) {
* This method is invoked by HotSpotDiagnosticMXBean.dumpThreads.
*/
public static void dumpThreadsToJson(OutputStream out) {
PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8);
BufferedOutputStream bos = new BufferedOutputStream(out);
PrintStream ps = new PrintStream(bos, false, StandardCharsets.UTF_8);
try {
dumpThreadsToJson(ps);
} finally {
ps.flush();
ps.flush(); // flushes underlying stream
}
}

Expand Down Expand Up @@ -257,13 +262,16 @@ private static void dumpThreadsToJson(ThreadContainer container,
*/
private static void dumpThreadToJson(Thread thread, PrintStream out, boolean more) {
out.println(" {");
out.format(" \"tid\": \"%d\",%n", thread.threadId());
out.format(" \"name\": \"%s\",%n", escape(thread.getName()));
out.format(" \"stack\": [%n");
out.println(" \"tid\": \"" + thread.threadId() + "\",");
out.println(" \"name\": \"" + escape(thread.getName()) + "\",");
out.println(" \"stack\": [");

int i = 0;
StackTraceElement[] stackTrace = thread.getStackTrace();
while (i < stackTrace.length) {
out.format(" \"%s\"", escape(stackTrace[i].toString()));
out.print(" \"");
out.print(escape(stackTrace[i].toString()));
out.print("\"");
i++;
if (i < stackTrace.length) {
out.println(",");
Expand Down

1 comment on commit 3c258ac

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.