spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.43k stars 40.52k forks source link

Investigate jcmd's json thread dump format #35782

Open wilkinsona opened 1 year ago

wilkinsona commented 1 year ago

As part of JEP 444, jcmd has gained the ability to generate a json-formatted thread dump:

$ jcmd <pid> Thread.dump_to_file -format=json <file>

We might be able to serve this format from actuator's threaddump endpoint.

mhalbritter commented 1 year ago

This seems to be the class which does the JSON dumping: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java

mhalbritter commented 1 year ago

There's a method on the HotSpotDiagnosticMXBean called dumpThreads which can produce a JSON formatted dump:

HotSpotDiagnosticMXBean bean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
if (bean == null) {
    throw new IllegalStateException("No HotSpotDiagnosticMXBean found");
}
Path file = Path.of("threads.json").toAbsolutePath();
Files.deleteIfExists(file);
bean.dumpThreads(file.toString(), ThreadDumpFormat.JSON);

It looks like this: threads.json.zip

Unfortunately it can only dump to files (which have to be given as an absolute path).

And, quoting from JEP 444:

The new thread dump format does not include object addresses, locks, JNI statistics, heap statistics, and other information that appears in traditional thread dumps. Moreover, because it might need to list a great many threads, generating a new thread dump does not pause the application.

mhalbritter commented 1 year ago

Interestingly

ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);

still dumps virtual threads, even JEP 444 states:

Unfortunately the JDK's traditional thread dump, obtained with jstack or jcmd, presents a flat list of threads. This is suitable for dozens or hundreds of platform threads, but is unsuitable for thousands or millions of virtual threads. Accordingly, we will not extend traditional thread dumps to include virtual threads.

Maybe this only applies when using jstack or jcmd.

Even the javadoc states:

Returns the thread info for all live platform threads with stack trace and synchronization information. The thread IDs of virtual threads are not included.

Which seems not be true at the time of writing.