No matter the size of your company, Azul offers competitive pricing options to fit your needs, your budget, and your ambition.
Forrester reports an 129% ROI by Optimizing Java Runtime Performance.
No matter the size of your company, Azul offers competitive pricing options to fit your needs, your budget, and your ambition.
Forrester reports an 129% ROI by Optimizing Java Runtime Performance.
JVM monitoring helps track runtime health, performance, and resource usage across Java applications. Track key metrics like CPU, memory, garbage collection, threads, and class loading, then use monitoring tools to spot issues and troubleshoot faster. At scale, Azul Intelligence Cloud gives visibility into all the JVMs running across your Java estate, helping to identify unused or outdated Java, optimize resources, and strengthen audit defense.
Java performance problems rarely come without warning. The challenge is noticing the signs early enough to act before they start disrupting operations.
JVM monitoring gives you the visibility to do that. This article covers what to watch, how to monitor it, and how to extend that visibility across your Java estate using Azul Intelligence Cloud.
Of all commercial vendors, Azul is one of the few vendors fully focused on Java. We understand the Java landscape from the inside out and built Azul Intelligence Cloud to give enterprises visibility into their Java estates.
The experience we gain daily helping customers monitor, manage, and optimize their Java environments informs the guidance in this article.
JVM monitoring is the process of continuously tracking the health, performance, and resource usage of a Java Virtual Machine (JVM).
Because your business applications rely on the JVM to manage resources like memory, threads, garbage collection and class loading, problems at the JVM level can affect application performance and stability.
JVM monitoring helps spot these problems, understand what is causing them, and act before they affect users.
It’s worth noting that JVM monitoring is different from application performance monitoring (APM). JVM monitoring focuses on the Java runtime itself, while APM focuses on what the application is doing, like requests, transactions, errors, and dependencies.
The two work together, though. APM can show you that an application is slowing down, while JVM monitoring can help you determine whether it’s a JVM issue that is causing the slowdown.
Proper JVM monitoring helps you:
Tracking memory, CPU, threads, and garbage collection can help you spot abnormal behavior before it affects application performance or availability.
Monitoring memory usage can help you identify memory leaks and other issues before they cause errors like OutOfMemoryError and take an application offline.
JVM metrics can help you determine whether slowdowns are related to memory pressure, excessive garbage collection, CPU usage, thread contention, or other runtime issues.
Identifying issues such as long garbage collection pauses and thread contention can help you reduce application slowdowns and freezes that users experience.
Monitoring shows how your JVMs use CPU and memory over time, helping you establish normal baselines and spot unusual changes.
Understanding your JVMs’ actual CPU and memory requirements can help you right-size cloud resources and avoid paying for capacity your applications don’t need.
Compare JVM behavior before and after JDK upgrades, application releases, configuration changes, or workload increases to identify unexpected effects.
Historical JVM data can show what happened around an incident, giving your team evidence to investigate instead of relying on guesswork.
No single JVM metric will tell you whether a Java application is healthy. You need to look at several metrics together, because changes in one area can affect another. The most useful JVM metrics fall into these categories:
Monitor how much CPU the JVM process is consuming and look at both short-term spikes and sustained high usage.
High CPU usage can result from increased application workload, inefficient code, excessive garbage collection, or high thread activity. Comparing JVM CPU usage with overall host or container CPU usage can also help you determine whether the JVM is actually consuming the available processing capacity.
Monitor heap usage, including used, committed, and maximum heap, along with non-heap memory like Metaspace.
Look at memory trends over time rather than relying on a single percentage. If heap usage continues to climb after garbage collection, for example, it can indicate that objects are not being released as expected and may point to a memory leak. Metaspace can also run out of memory when its configured limit is reached, resulting in an OutOfMemoryError.
Track GC frequency, pause duration, and the amount of time spent in garbage collection.
Long GC pauses can increase application latency, while frequent or lengthy GC activity can leave less time for the application to execute its own work. Rather than looking for a single “good” GC number, establish a baseline for your workload and watch for changes like increasingly frequent collections or longer pauses that coincide with rising application latency.
Monitor live thread count and the states of those threads, including runnable, blocked, waiting, and timed waiting.
A sudden increase in thread count can indicate requests or tasks are backing up. Large numbers of blocked or waiting threads can point to contention, while deadlocked threads can leave parts of an application unable to make progress.
Track the number of loaded and unloaded classes and watch for unexpected growth.
Changes in class-loading behavior can help you investigate unusual application behavior or potential classloader problems, particularly when the number of loaded classes continues to increase unexpectedly.
Monitor JIT compilation activity when you’re investigating JVM performance or application warm-up.
The JIT compiler uses runtime information to compile frequently executed Java bytecode into native machine code, and this compilation consumes CPU. Changes in compilation behavior can therefore help explain changes in CPU usage or performance.
Finally, track information about the JVM itself, including:
This information helps you understand what runtime you’re actually monitoring and how it’s configured. Oracle’s Java management documentation exposes this type of runtime information alongside metrics for memory, threads, garbage collection, class loading, and the operating system.
Java already includes built-in monitoring and management capabilities through the java.lang.management API and JMX (Java Management Extensions). Through these interfaces, you can access and expose important metrics using two methods:
You can enable the JMX management agent when starting your application and connect to the JVM with a JMX-compatible monitoring tool. JConsole, for example, uses JMX to monitor JVM performance and resource consumption.
For a remote JVM, however, don’t use an unauthenticated, non-SSL JMX configuration in production. Remote JMX should be secured with authentication and SSL/TLS. For local troubleshooting, JConsole can connect directly to applications running on the same machine.
If you’re building a Spring Boot application, another option is Micrometer. Spring Boot Actuator automatically configures JVM metrics through Micrometer, so you can expose them to your monitoring system without setting up JMX directly.
Once your JVM is exposing metrics, you need somewhere to collect, store, and visualize them. Your options generally fall into three categories, depending on your existing infrastructure and how much monitoring infrastructure you want to manage yourself:
For a self-hosted monitoring stack, you can combine:
You can use a pre-built JVM dashboard or create your own based on the metrics that matter to your applications.
Platforms like Datadog, Dynatrace, and New Relic can collect JVM metrics alongside application and infrastructure telemetry.
Depending on the platform, you typically install or attach a Java agent to your application, configure the required telemetry, and then view JVM metrics and application performance data through the provider’s dashboards. This approach reduces the monitoring infrastructure you need to operate yourself.
If you’re already using OpenTelemetry, you can collect JMX metrics and export them alongside other telemetry. OpenTelemetry’s Java implementation currently supports stable metrics, traces, and logs, and its JMX metrics tooling can collect JVM metrics like memory, GC, and threads.
P.S. These approaches aren’t mutually exclusive. For example, you could use Micrometer to expose metrics, Prometheus to collect them, and Grafana to visualize them.
Once you’re collecting JVM metrics, establish a baseline for each application before deciding what should trigger an alert.
Avoid applying universal thresholds such as “alert when heap exceeds 85%” or “alert when GC pauses exceed two seconds.” What constitutes a problem depends on the application’s workload, JVM configuration, garbage collector, and normal operating range.
Instead, look for meaningful changes in behavior. For example:
For deeper investigation, use the JDK’s diagnostic tools when your metrics show that something is wrong but don’t explain why.
JDK Flight Recorder (JFR) can collect detailed runtime and application events, while JDK Mission Control (JMC) provides tools for analyzing JFR recordings and monitoring JVMs.
The jcmd utility can also send diagnostic commands to a running JVM, including commands for starting and managing JFR recordings. Oracle currently recommends jcmd over older utilities like jstack, jinfo, and jmap for many diagnostic tasks.
Monitoring an individual JVM is useful, but at enterprise scale, you also need to know what Java is actually running across your estate.
That means maintaining an up-to-date inventory of your Java deployments: which JVMs are running, where they’re deployed, which vendors and versions they use, which applications they’re running, and whether they’re actually in use.
This visibility can help with everything from identifying outdated or unused JVMs to understanding your Oracle Java footprint for licensing and audit purposes.
But keeping this information accurate across hundreds or thousands of JVMs is difficult. Java deployments change constantly as applications are updated, new workloads are introduced, and old ones are retired. So, point-in-time discovery can quickly become outdated, leaving your IT team without a reliable view of what is actually running.
That is where most organizations bring in Azul Intelligence Cloud.
Azul Intelligence Cloud continuously monitors your Java estate across JVM vendors and distributions. Its JVM Inventory captures details like vendor, version, installation path, and associated applications, giving your team a current view of what’s actually running.
For organizations managing Oracle Java, this can help identify Oracle JVMs that are still in use, find unused installations to remove, and determine which workloads need to be migrated. After a migration, Azul Intelligence Cloud can also detect newly introduced Oracle Java instances, helping prevent new licensing exposure.
And because Azul Intelligence Cloud uses production runtime data, you can also see how your Java workloads are behaving and identify where applications or code may be going unused. That gives your team a better basis for deciding which JVMs to keep, remove, migrate, or optimize.
One global online services platform used Intelligence Cloud to analyze its Java estate and found that nearly 50% of its application code was going unused. Engineers were spending 10% of their time maintaining dead and unused code, and the customer identified the potential to recover developer capacity equivalent to 30 full-time developers by eliminating wasted work.
Want to see what’s actually running across your Java estate? Book an Azul Intelligence Cloud Demo to get continuous visibility into your JVMs, applications, and Java environment.
JVM monitoring gives you the visibility to catch runtime problems before they become operational issues. But as your Java environment grows, it becomes just as important to have a clear picture of what’s running, where, and whether those JVMs still need to be there.
Azul Intelligence Cloud brings that visibility together, helping you understand your Java environment, spot unused or outdated JVMs, and decide what to keep, remove, or investigate.
Want to get a deeper look at your Java environment? Then, check out Azul’s guide to Java discovery and inventory or book an Azul Intelligence Cloud demo to start getting continuous visibility into your JVMs and Java applications.