Skip to content

Instantly share code, notes, and snippets.

@sirmax
Created March 22, 2022 13:58
Show Gist options
  • Save sirmax/e9b961cd11bc404a0ea75d2456d76e6a to your computer and use it in GitHub Desktop.
Save sirmax/e9b961cd11bc404a0ea75d2456d76e6a to your computer and use it in GitHub Desktop.
OpenJDK 17.0.2 native memory leak in Tracing area
import javax.management.MBeanServer;
import javax.management.ObjectName;
// Run with `-XX:NativeMemoryTracking=detail`.
// Use `jcmd Leak VM.native_memory detail | fgrep -B4 -A2 Tracing`,
// observe the changes in `Tracing` area and related details. E.g.:
//
//- Tracing (reserved=1089KB, committed=1089KB)
// (malloc=2KB #43)
// (arena=1087KB #34)
//--
//[0x0000000103c2f358] JfrDCmd::argument_info_array() const+0x1d0
//[0x0000000103ed3c38] jmm_GetDiagnosticCommandArgumentsInfo+0x134
//[0x00000001028e9c6c] getDiagnosticCommandArgumentInfoArray+0x78
//[0x00000001028ea0c4] Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo+0x198
// (malloc=2KB type=Tracing #34)
public class Leak {
public static void main(String[] args) throws Throwable {
ObjectName name = ObjectName.getInstance("com.sun.management:type=DiagnosticCommand");
MBeanServer server = java.lang.management.ManagementFactory.getPlatformMBeanServer();
while (true) {
// In actual applications this could be a thread pool that recycles threads.
new Thread(() -> {
try {
// getMBeanInfo goes into the native code, that allocates a thread-local pointer
// to a new arena, but never frees that arena after the thread terminates.
// See https://github.com/openjdk/jdk/blob/jdk-17+35/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp#L299
server.getMBeanInfo(name);
} catch (Throwable e) {
e.printStackTrace();
}
}).start();
Thread.sleep(1000L);
}
}
}
@sirmax
Copy link
Author

sirmax commented Mar 23, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment