JVM has multiple internal memory regions. Native Memory Tracking (NMT) helps Java developers to identify memory leaks, excessive memory usage, and other related issues on these internal memory regions by providing detailed information on each memory region. In this post, let’s learn how to use NMT to troubleshoot JVM memory related problems.
Video
In this video, let’s learn how to use NMT to troubleshoot JVM memory related problems.
What is Native Memory Tracking (NMT)?

JVM Memory has following internal regions:
- Heap Memory (Young Generation, Old Generation)
- Metaspace
- Threads
- Code Cache
- Direct Buffer
- GC
- JNI
- NMT
- Misc
If you are interested, you can watch this video clip to learn more about these JVM internal memory regions.
NMT is a feature of the Java Virtual Machine (JVM) that tracks and reports all the JVM memory regions usage.
Benefits of Using NMT
NMT is primarily used to identify memory leaks in the native memory regions. By analyzing NMT data, we can isolate which region in the native memory is always growing and not getting freed up. It would facilitate isolating the root cause of OutOfMemoryError.
What is the difference between Garbage Collection Log and NMT?
Garbage Collection logs contain finest details about the Java Heap space (i.e. Young Generation, Old Generation) and Metaspace usage and garbage collection metrics (at what time it ran, like how long each GC event ran, how much memory recovered after each GC event…). However, it doesn’t contain details about the native memory regions.
On the other hand, NMT contains details only about native memory regions size.
When to use Garbage Collection Log and NMT?
If you are trying to optimize Garbage Collection performance or troubleshoot memory leak in the Java Heap space or Metaspace, then you need to use GC Log.
If you are trying to isolate memory leaks in native memory regions, then you need to use NMT data.
How to Enable NMT
NMT is not enabled by default in the JVM, so you need to explicitly turn it on. You can enable NMT by passing the -XX:NativeMemoryTracking option to the JVM with either the summary or detail level. The summary level provides a high-level overview, while the detail level offers more granular information.
java -XX:NativeMemoryTracking=summary -jar YourApplication.jar
or for detailed tracking:
java -XX:NativeMemoryTracking=detail -jar YourApplication.jar
Capture NMT Data
Once NMT is enabled, you can capture and analyze the native memory usage data in several ways:
1. Using jcmd
The jcmd utility is a powerful tool that comes with the JDK. You can use it to request various diagnostics from a running JVM, including NMT statistics.
jcmd <pid> VM.native_memory summary > nmt_report.txt
or for detailed information:
jcmd <pid> VM.native_memory detail > nmt_report.txt
Replace <pid> with the process ID of your running Java application.
2. Periodically Capturing Data
For long-running applications, it might be useful to capture NMT data periodically. This can be achieved by setting up a cron job or a scheduled task that runs the jcmd command at regular intervals.
Analyze NMT using GCeasy
While NMT provides valuable insights, analyzing raw NMT data can be complex and time-consuming. This is where GCeasy comes into play. GCeasy is a powerful tool that simplifies the analysis of JVM memory reports, including NMT reports. It provides a user-friendly interface and detailed visualizations to help you understand memory usage patterns and identify potential issues.
Steps to Analyze NMT Reports with GCeasy
1. Upload NMT file to GCeasy: Go to the GCeasy website and upload the captured NMT file.
2. Analyze the Report: GCeasy will parse the NMT file and present the data in an easy-to-understand format. You will see visualizations and detailed breakdowns of memory usage across different components like Java Heap, Class, Thread, Code, and GC.

3. JVM Memory Regions Trend: GCeasy presents you with the trending report of each JVM memory region as well. In this section, for each memory region following data will be reported:
- Reserved size is the total amount of memory that the JVM has reserved from the operating system.
- Committed size refers to the amount of memory that the JVM has allocated from the operating system and is currently using.
4. Identify Issues: By analyzing the trends in committed and reserved size, you can identify patterns and potential issues. For instance, a steady increase in committed memory might indicate a memory leak, while significant fluctuations in reserved memory could suggest that the JVM is frequently resizing its memory pools. Monitoring these trends helps maintain optimal performance and stability of your application. For example: If you observe the below image, GCeasy is highlighting the issues in the Native Memory Tracking report.

Also read: The 7 most important JVM arguments that you can pass to JVM around Garbage collection and memory to make your application more effective.
Conclusion
Native Memory Tracking (NMT) is an extremely light-weight artifact that you can use to detect and address memory leaks and inefficiencies across various memory regions. Tools like GCeasy further streamline this process, transforming raw NMT data into actionable insights through user-friendly visualizations. Regular monitoring with NMT not only aids in quick troubleshooting but also ensures your application runs optimally, providing a robust foundation for sustained performance improvements.


5 Pingback