Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 3771

Monitor Non-Heap Memory Usage of a JVM

$
0
0

1. Overview

Using a Java application, we sometimes face issues with memory consumption. In general, we can categorize all problems into those based on heap memory usage and those based on non-heap memory usage.

In this article, we’ll review different tools that we can use to monitor non-heap memory utilization.

2. jcmd

jcmd is a JDK tool we can use to send diagnostic and troubleshooting commands to a running Java process. We utilize it to inspect system properties, trigger garbage collection, dump heap and thread information, and manage JIT compilation.

To monitor non-heap memory using jcmd, we need to enable native memory tracking. Then we can call jcmd to get the memory process information:

jcmd <pid> VM.native_memory

In the response, we can analyze all the non-heap sections we need:

-                        GC (reserved=359872KB, committed=70440KB)
                            (malloc=17792KB #582)
                            (mmap: reserved=342080KB, committed=52648KB)
-                  Compiler (reserved=168KB, committed=168KB)
                            (malloc=4KB #29)
                            (arena=165KB #5)
-                  Internal (reserved=221KB, committed=221KB)
                            (malloc=157KB #1202)
                            (mmap: reserved=64KB, committed=64KB)
-                     Other (reserved=4KB, committed=4KB)
                            (malloc=4KB #2)
-                    Symbol (reserved=1217KB, committed=1217KB)
                            (malloc=857KB #3546)
                            (arena=360KB #1)
-    Native Memory Tracking (reserved=141KB, committed=141KB)
                            (malloc=5KB #69)
                            (tracking overhead=136KB)
//shorten

In the output, we can see the heap memory consumption as well as the consumption of all non-heap memory types. The committed property indicates the consumption at the moment of the jcmd call.

3. jconsole

jconsole is a monitoring tool that complies with the JMX specification. We can use jconsole to monitor and manage Java applications in real-time in cases when we have access only to the JDK.

Jconsole provides a graphical interface to track memory usage, thread activity, CPU consumption, and MBeans. The tool connects to local or remote JVMs, helping us diagnose performance issues and optimize application behavior.

To run jconsole, we run the following command from the JDK bin folder:

<JDK_PATH>\bin\jconsole

On the first screen, we select the local or remote process we want to connect to:

 

On the Memory tab, we select the Non-Heap Memory Usage chart. After that, we’re able to see the graph of the non-heap usage:

 

4. VisualVM

VisualVM is another visual tool that provides JVM monitoring capabilities. We use VisualVM to monitor CPU load, memory usage, thread activity, and heap dumps. VisualVM also supports analyzing thread dumps and profiling method execution to identify performance bottlenecks.

4.1. Monitor MetaSpace in Basic Monitor

In the basic VisualVM setup, we’re able to monitor the metaspace size using the Monitor tab:

 

To monitor other non-heap sections, we can install additional VisualVM plugins.

4.2. Monitor Non-heap Memory Using Mbeans Plugin

By adding the MBeans VisualVM plugin, we’ll see the new MBeans tab. On this tab, we can view the current non-heap memory usage in general and for specific memory sections in particular:

 

4.3. Monitor Direct Buffers Using Buffer Pools Plugin

Additionally, we can use the Buffer Monitor VisualVM plugin. After the installation we’ll see the new Buffer Pools tab, where we can view the current direct buffer memory and memory-mapped files usage:

5. Java Mission Control

Java Mission Control is one more visual tool that provides JVM monitoring and diagnostics capabilities. We utilize JMC to analyze application performance, monitor memory usage, inspect thread activity, and review garbage collection behavior.

JMC also supports profiling method executions and analyzing flight recordings to identify performance bottlenecks.

5.1. Non-Heap Memory Usage Using MBean Browser

Let’s connect to our application using the MBean Server. On the MBeans Browser tab, we can find the total utilization of non-heap memory. However, we should be aware that this number doesn’t include direct buffer memory consumption:

 

If we select the section under the BufferPool group, we can find the usage of direct pool memory:

5.2. Native Memory Tracking Using JFR Records

Since Java 20, we’re also able to record the Native Memory Tracking data continuously with JFR. Using the next command, we can prepare a flight recorder file with the needed events tracked:

java -XX:NativeMemoryTracking=detail -XX:StartFlightRecording=name=Profiling,filename=nmt-recording.jfr,settings=profile  -jar path/ourapp.jar

Then, we can open this file using Java Mission Control:

 

On the Event Browser tab of the recording, we can find the Event Types Tree. Inside it, we can find the Total Native Memory Usage event. If we select it, the right side of the screen displays the total amount of committed memory. This number includes both heap and non-heap memory consumption.

Additionally, we can choose the Native Memory Usage Per Type event. In this case, we see a breakdown of the consumption for all non-heap memory types:

6. JMX-DExporter

JMX-DExporter is a tool that exposes JMX metrics in a format compatible with Prometheus. We can use JMX-DExporter to collect JVM metrics such as memory usage, thread activity, garbage collection statistics, and more.

6.1. Metrics Endpoint Usage

To start using JMX-DExporter, first of all, we need to download the agent JAR. Then, we configure our exporter using jmx_exporter_config.yml:

startDelaySeconds: 0
lowercaseOutputName: true
lowercaseOutputLabelNames: true
rules:
  - pattern: "java.lang:type=Memory"
    name: "jvm_memory_usage_bytes"
    labels:
      area: "$2"
    type: GAUGE

In this example, we’ve configured the java.lang:type=Memory pattern. This means we want to export the MemoryMXBean data to our metrics endpoint.  Now, we’re able to start our application with the JMX-DExporter attached to it:

java -javaagent:.path-to-agent-jar\jmx_prometheus_javaagent.jar=port:path-to-agent-jar\jmx_exporter_config.yml -jar .path-to-app\app.jar

In the start command, we specify the path to the downloaded agent JAR and the port on which the new metrics endpoint will be available. For this purpose, we use the javaagent parameter. Additionally, we specify the path to the configuration file and the JAR file of our application.

Now, if we call the http://localhost:port/metrics endpoint, we see the complete information provided by the memory MBean, including the non-heap memory usage data:

//shorten
jvm_memory_committed_bytes{area="nonheap"} 1.8546688E7
# HELP jvm_memory_init_bytes Initial bytes of a given JVM memory area.
# TYPE jvm_memory_init_bytes gauge
jvm_memory_init_bytes{area="heap"} 5.32676608E8
jvm_memory_init_bytes{area="nonheap"} 7667712.0
# HELP jvm_memory_max_bytes Max (bytes) of a given JVM memory area.
# TYPE jvm_memory_max_bytes gauge
jvm_memory_max_bytes{area="heap"} 8.518631424E9
jvm_memory_max_bytes{area="nonheap"} -1.0
//shorten

6.2. Integration With Prometheus

Prometheus is an open-source monitoring and alerting toolkit that we use to collect and store metrics as time series data. We can easily integrate our metrics endpoint with Prometheus.

After installing the Prometheus instance, we modify the prometheus.yml file with the following values:

scrape_configs:
  - job_name: "our_app"
    static_configs:
      - targets: ["localhost:port"]

In the job_name property, we specify how our Prometheus target will be named. In the targets property, we specify the host and port of our metrics endpoint.

After making the configuration changes, we need to restart the Prometheus instance and open the console. In the input field, we can type any available metric, including the non-heap usage. After this, the memory metric graph will be shown on the screen:

7. Conclusion

In this tutorial, we reviewed a set of tools that help us monitor non-heap memory usage.

For simple cases, when we don’t need a detailed report and have access to the JDK, we can consider basic tools like directly using jcmd or the jconsole. For more complex cases, where detailed insights into specific memory types are needed, we can use flight recording and JMC.

To integrate our monitoring into Prometheus metrics, we can use the JMX-Exporter agent. The additional resource consumption of all monitoring tools should be taken into account in each specific case.

The post Monitor Non-Heap Memory Usage of a JVM first appeared on Baeldung.
       

Viewing all articles
Browse latest Browse all 3771

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>