Java8 introduces Native Memory Tracking (NMT) to HotSpot VM, which can be used to track the internal Memory usage of the JVM and can be accessed via JCMD. Note, however, that NMT implements memory tracking by adding trace points to JVM code, so NMT cannot track memory usage of third party Native libraries.

How do I start NMT?

-xx :NativeMemoryTracking=summary can be used to enable NMT, where the value is off by default and can be set to summary or detail. When enabled, the performance cost increases by about 5-10%

-XX:NativeMemoryTracking=[off | summary | detail]
Copy the code

Parameters that

Note that according to the Official Java documentation, there is a 5%-10% performance penalty for enabling NMT;

If you want to print the memory usage when the JVM exits, you can use the following configuration items:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics
Copy the code

How do I access NMT data?

We can view NMT reports through JCMD and see the comparison.

Native_memory (JCMD PID VM. Native_memory), which can be followed by summary or detail. If summary is enabled, only summary can be used. The scale parameter can specify the display unit, which can be KB, MB, or GB

jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]
Copy the code

Parameters that

To see the details, I also have JVisualVM turned on locally (I won’t say much about JVisualVM here, more on that in the next few installments), and the thread ID can be seen directly. Of course, you can query the corresponding application thread

View NMT reports using JCMD

  • It can be seen that the whole memory mainly includes Java Heap, Class, Thread, Code, GC, Compiler, Internal, Other, Symbol, Native Memory Tracking, Arena Chunk. Reserved indicates the available memory size of an application, while COMMITTED indicates the memory size that an application is using
  • The Java Heap section indicates that the Heap memory currently occupies 4246MB; The Class section indicates that 1131 classes have been loaded, and the Thread section indicates that 169 threads are currently loaded, occupying 169MB. The Code part indicates that the JIT-generated or cached instructions occupy 251MB; The GC section indicates that 162MB of memory is currently used to help GC; The Code part indicates that compiler takes 26MB when generating Code. The Internal part indicates that command line parsing and JVMTI occupy 5MB. The Other field indicates that uncategorized items occupy 2MB. The Symbol part indicates that symbols such as String table and constant pool occupy 10MB; The Native Memory Tracking section indicates that the feature itself takes up 6MB.
  • An arena represents a chunk of memory allocated using MALLOc. These chunks can be used by other SUBSYSTEMS as temporary memory, such as the allocation of pre-threads, whose memory is freed as bulk

Parameters that

  • Java Heap: Heap memory, i.e-XmxLimit the maximum heap size of memory.
  • Metaspace: metadata that contains information about classes and methods to be loaded-XX:MaxMetaspaceSizeLimit the maximum size, the other is class space, by-XX:CompressedClassSpaceSizeLimit maximum size
  • Thread: Thread and Thread stack occupy memory, the size of each Thread stack-XssLimit, but there is no limit to the total size.
  • Code: JIT just-in-time compiled (C1 C2 compiler optimized) Code takes up memory, subject to-XX:ReservedCodeCacheSizelimit
  • GC: Garbage collection takes up memory, such as CardTable, tag count, partition records, tag GC Root, etc. It’s not restricted, it’s usually not very big.
  • The memory used by the C2 Compiler’s own code and markup is not limited and is generally not very large
  • Internal: The amount of memory used by JVMTI for command line parsing. This is unlimited and generally not very large
  • Symbol: Size occupied by the string constant pool-XX:StringTableSizeNumber limit, total memory size is not limited
  • Native Memory Tracking: The size of the Memory used by the acquisition itself, if not enabled, will not be used, this is not limited, generally not very large
  • Arena Chunk: All memory allocated via Arena. This is unlimited and usually not very large
  • Tracing: Memory occupied by all collections. If JFR is enabled, it is mainly the memory occupied by JFR. It’s not restricted, it’s usually not very big
  • Logging, Arguments, Module, Synchronizer, Safepoint, and Other are things we don’t care about.

conclusion

NMT is very efficient for tracking the internal memory usage of the JVM. Just a quick review of a few points

  • Java8 introduces Native Memory Tracking (NMT) to HotSpot VM, which can be used to track internal Memory usage of the JVM
  • -xx :NativeMemoryTracking=summary can be used to enable NMT. The default value is off. You can set summary and detail to enable NMT. If enabled, the performance cost increases by about 5%-10%. Use – XX: + UnlockDiagnosticVMOptions – XX: + PrintNMTStatistics can the JVM when shutdown of the output of the whole native memory statistics; You can run the JCMD pid VM. Native_memory commands to view, diff, and shutdown other commands
  • The whole memory mainly includes Java Heap, Class, Thread, Code, GC, Compiler, Internal, Other, Symbol, Native Memory Tracking, Arena Chunk. Reserved indicates the available memory size of an application, while COMMITTED indicates the memory size that an application is using

How to track the internal Memory usage of a JVM using Native Memory Tracking?