Thread.dump_to_file time
Gillespie, Oli
ogillesp at amazon.co.uk
Wed Sep 6 09:36:11 UTC 2023
Some quick profiling suggests the main cost (on my aarch64 mac and also my x86 linux) is the huge number of write syscalls. It seems the file output stream is unbuffered. However I don't see significant speed difference between my mac and linux hosts.
100 threads of stack depth 100 in json format causes 43692 write calls, wrapping in a BufferedOutputStream and disabling PrintStream's autoflush brings it down to 105 write calls.
10,000 threads of depth 100 in json format takes me 8 seconds currently, and under 3 seconds with the buffer added.
If anyone wants to make this change or similar that's fine by me, otherwise I may get round to it at some point.
Oli
Patch and test code:
diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java b/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java
index 53a3e3694f1..24024387c97 100644
--- a/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java
+++ b/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java
@@ -25,6 +25,7 @@
package jdk.internal.vm;
import java.io.ByteArrayOutputStream;
+import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
@@ -109,8 +110,8 @@ private static byte[] dumpThreadsToFile(String file, boolean okayToOverwrite, bo
? new OpenOption[0]
: new OpenOption[] { StandardOpenOption.CREATE_NEW };
String reply;
- try (OutputStream out = Files.newOutputStream(path, options);
- PrintStream ps = new PrintStream(out, true, StandardCharsets.UTF_8)) {
+ try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(path, options));
+ PrintStream ps = new PrintStream(out, false, StandardCharsets.UTF_8)) {
if (json) {
dumpThreadsToJson(ps);
} else {
public class ThreadDumpPerf {
public static void main(String[] args) throws Exception {
int depth = Integer.parseInt(args[0]);
int numThreads = Integer.parseInt(args[1]);
for (int t = 0; t < numThreads; t++) {
new Thread(() -> recurse(depth)).start();
}
System.out.printf("Started %d threads with stack depth %d. pid=%d\n", numThreads, depth, ProcessHandle.current().pid());
}
static void recurse(int depth) {
if (depth == 0) {
try {
Thread.sleep(1_000_000);
return;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
recurse(depth - 1);
}
}
Amazon Development Centre (London) Ltd. Registered in England and Wales with registration number 04543232 with its registered office at 1 Principal Place, Worship Street, London EC2A 2FA, United Kingdom.
More information about the loom-dev
mailing list