Add support for dumping the heap on OpenJ9

Closes gh-26466
pull/27538/head
Andy Wilkinson 3 years ago
parent e30bf0e3e5
commit 64c0eceec7

@ -7,7 +7,10 @@ The `heapdump` endpoint provides a heap dump from the application's JVM.
[[heapdump.retrieving]]
== Retrieving the Heap Dump
To retrieve the heap dump, make a `GET` request to `/actuator/heapdump`.
The response is binary data in https://docs.oracle.com/javase/8/docs/technotes/samples/hprof.html[HPROF] format and can be large.
The response is binary data and can be large.
Its format depends upon the JVM on which the application is running.
When running on a HotSpot JVM the format is https://docs.oracle.com/javase/8/docs/technotes/samples/hprof.html[HPROF]
and on OpenJ9 it is https://www.eclipse.org/openj9/docs/dump_heapdump/#portable-heap-dump-phd-format[PHD].
Typically, you should save the response to disk for subsequent analysis.
When using curl, this can be achieved by using the `-O` option, as shown in the following example:

@ -100,26 +100,38 @@ public class HeapDumpWebEndpoint {
if (this.heapDumper == null) {
this.heapDumper = createHeapDumper();
}
File file = createTempFile(live);
File file = createTempFile();
this.heapDumper.dumpHeap(file, live);
return new TemporaryFileSystemResource(file);
}
private File createTempFile(boolean live) throws IOException {
private File createTempFile() throws IOException {
String date = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm").format(LocalDateTime.now());
File file = File.createTempFile("heapdump" + date + (live ? "-live" : ""), ".hprof");
File file = File.createTempFile("heap-" + date, "." + determineDumpSuffix());
file.delete();
return file;
}
private String determineDumpSuffix() {
if (this.heapDumper instanceof OpenJ9DiagnosticsMXBeanHeapDumper) {
return "phd";
}
return "hprof";
}
/**
* Factory method used to create the {@link HeapDumper}.
* @return the heap dumper to use
* @throws HeapDumperUnavailableException if the heap dumper cannot be created
*/
protected HeapDumper createHeapDumper() throws HeapDumperUnavailableException {
try {
return new HotSpotDiagnosticMXBeanHeapDumper();
}
catch (HeapDumperUnavailableException ex) {
return new OpenJ9DiagnosticsMXBeanHeapDumper();
}
}
/**
* Strategy interface used to dump the heap to a file.
@ -140,8 +152,8 @@ public class HeapDumpWebEndpoint {
}
/**
* {@link HeapDumper} that uses {@code com.sun.management.HotSpotDiagnosticMXBean}
* available on Oracle and OpenJDK to dump the heap to a file.
* {@link HeapDumper} that uses {@code com.sun.management.HotSpotDiagnosticMXBean},
* available on Oracle and OpenJDK, to dump the heap to a file.
*/
protected static class HotSpotDiagnosticMXBeanHeapDumper implements HeapDumper {
@ -171,6 +183,38 @@ public class HeapDumpWebEndpoint {
}
/**
* {@link HeapDumper} that uses
* {@code openj9.lang.management.OpenJ9DiagnosticsMXBean}, available on OpenJ9, to
* dump the heap to a file.
*/
private static final class OpenJ9DiagnosticsMXBeanHeapDumper implements HeapDumper {
private Object diagnosticMXBean;
private Method dumpHeapMethod;
@SuppressWarnings("unchecked")
private OpenJ9DiagnosticsMXBeanHeapDumper() {
try {
Class<?> mxBeanClass = ClassUtils.resolveClassName("openj9.lang.management.OpenJ9DiagnosticsMXBean",
null);
this.diagnosticMXBean = ManagementFactory.getPlatformMXBean((Class<PlatformManagedObject>) mxBeanClass);
this.dumpHeapMethod = ReflectionUtils.findMethod(mxBeanClass, "triggerDumpToFile", String.class,
String.class);
}
catch (Throwable ex) {
throw new HeapDumperUnavailableException("Unable to locate OpenJ9DiagnosticsMXBean", ex);
}
}
@Override
public void dumpHeap(File file, boolean live) throws IOException, InterruptedException {
ReflectionUtils.invokeMethod(this.dumpHeapMethod, this.diagnosticMXBean, "heap", file.getAbsolutePath());
}
}
/**
* Exception to be thrown if the {@link HeapDumper} cannot be created.
*/

@ -97,8 +97,9 @@ If your application is a web application (Spring MVC, Spring WebFlux, or Jersey)
| ID | Description
| `heapdump`
| Returns an `hprof` heap dump file.
Requires a HotSpot JVM.
| Returns a heap dump file.
On a HotSpot JVM, an `HPROF`-format file is returned.
On an OpenJ9 JVM, a `PHD`-format file is returned.
| `jolokia`
| Exposes JMX beans over HTTP (when Jolokia is on the classpath, not available for WebFlux).

Loading…
Cancel
Save