8315702: jcmd Thread.dump_to_file slow with millions of virtual threads

Backport-of: 3c258ac907
This commit is contained in:
Rob McKenna
2023-09-15 19:07:20 +00:00
committed by Vitaly Provodin
parent c626930ca7
commit dca4cbcaec

View File

@@ -24,6 +24,7 @@
*/
package jdk.internal.vm;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -110,7 +111,8 @@ public class ThreadDumper {
: 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 {
@@ -132,11 +134,12 @@ public class ThreadDumper {
* 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
}
}
@@ -158,9 +161,10 @@ public class ThreadDumper {
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();
}
@@ -171,11 +175,12 @@ public class ThreadDumper {
* 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
}
}
@@ -257,13 +262,16 @@ public class ThreadDumper {
*/
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(",");