All Products
Search
Document Center

Application Real-Time Monitoring Service:JVM metrics

Last Updated:Jun 05, 2025

This topic describes how metrics related to Java virtual machine (JVM) memory, GC, threads, classes, and file descriptors are collected.

Memory metrics

The ARMS agent has a scheduled task that periodically calls the JDK interface java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class<T>) with the parameter java.lang.management.MemoryPoolMXBean.class to obtain memory metrics.

This method returns a list where each object in the list reflects the expected memory usage of different memory spaces in the JVM. The following code snippet demonstrates how to use this method.

public static void printCurrentJVMMemoryUsage() {
    List<MemoryPoolMXBean> beans = ManagementFactory.getPlatformMXBeans(MemoryPoolMXBean.class);
    for (MemoryPoolMXBean bean : beans) {
        System.out.printf("area=%s\tname=%s\tinitial=%d\tmax=%d\tcommited=%d\tuse=%d\n", bean.getType().name(),
                bean.getName(), bean.getUsage().getInit(), bean.getUsage().getMax(), bean.getUsage().getCommitted(), bean.getUsage().getUsed());
    }
}

The output of this code snippet may vary across different JVM versions. A possible output is shown as follows, which includes the type, name, initial size, maximum size, committed size, and used size of each memory space.

area=NON_HEAP	name=Code Cache	initial=2555904	max=134217728	commited=3211264	use=3139712
area=NON_HEAP	name=Metaspace	initial=0	max=-1	commited=8388608	use=7950584
area=NON_HEAP	name=Compressed Class Space	initial=0	max=1073741824	commited=1048576	use=919408
area=HEAP	name=PS Eden Space	initial=67108864	max=1409286144	commited=67108864	use=39057856
area=HEAP	name=PS Survivor Space	initial=11010048	max=11010048	commited=11010048	use=0
area=HEAP	name=PS Old Gen	initial=179306496	max=2863661056	commited=179306496	use=0

The ARMS agent periodically collects this data, and upon collection, it directly reports and records these metrics without any additional processing, as detailed in the following table.

Metric

Description

arms_jvm_mem_init_bytes

The initial memory size.

arms_jvm_mem_max_bytes

The maximum memory size.

arms_jvm_mem_committed_bytes

The committed memory size.

arms_jvm_mem_used_bytes

The used memory size.

The following table describes two key dimensions.

Dimension

Description

Example

area

The memory space type.

heap, nonheap

id

The memory space name.

eden, survivor, total

For information about JVM memory spaces, see JVM memory details.

GC metrics

  • Agents earlier than V4.4.0: Metrics are retrieved by a scheduled task that periodically calls the JDK interface java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class<T>) and passes the java.lang.management.GarbageCollectorMXBean parameter.

  • Agents V4.4.0 and later: Metrics are retrieved by subscribing to the GarbageCollectionNotificationInfo event of GarbageCollectionNotificationInfo.

This method returns a list where each object in the list reflects the status of different garbage collectors in the JVM. The following code snippet demonstrates how to use this method.

public static void printGC() {
    List<GarbageCollectorMXBean> beans = ManagementFactory.getPlatformMXBeans(GarbageCollectorMXBean.class);
    for (GarbageCollectorMXBean  bean : beans) {
        System.out.printf("name=%s\tgcCount=%d\tgcTime=%d\n", bean.getName(),
                bean.getCollectionCount(), bean.getCollectionTime());
    }
}

The output of this code snippet may vary across different JVM versions. A possible output is shown as follows, which includes the name of each garbage collector, the number of garbage collection (GC) occurrences, and the GC time consumed.

name=PS Scavenge	gcCount=0	gcTime=0
name=PS MarkSweep	gcCount=0	gcTime=0

Note that, since this data records cumulative values since the JVM was started, after periodically collecting this data, the ARMS agent subtracts the value obtained from the previous collection to calculate the number of GC occurrences and the GC time consumed within the current period (default 15 seconds). It then reports and records these metrics as described in the following table.

Note
  • Z garbage collector (ZGC) and Shenandoah:

    • Pauses: stop-the-world (STW) duration, typically shorter than 1 ms

    • Cycles: total duration for a GC

  • Others: Latency metrics exclusively measure the STW duration, that is, when all Java application threads are suspended for GCs.

Metric

Description

arms_jvm_gc_delta

The number of GC occurrences in the current cycle.

arms_jvm_gc_seconds_delta

The GC time consumed in the current cycle.

Considering the variety of actual garbage collectors, to reduce user comprehension costs, the ARMS agent maps the actual garbage collector names to "Young" and "Old," and records them in the dimensions listed in the following table.

Dimension

Description

Example

gen

The GC type.

young, old

cause

The GC trigger, supported in agents V4.4.0 and later.

System.gc(), Heap Dump Initiated GC, Allocation Failure

The following table describes the mapping relationships.

Garbage collector name

Gen value

Copy

young

G1 Young Gen

young

G1 Old Gen

old

G1 Young Generation

young

G1 Old Generation

old

ParNew

young

ConMarkSweep

old

ConcurrentMarkSweep

old

PS Scavenge

young

PS MarkSweep

old

PS Serial

young

MarkSweepCompact

old

Due to significant changes in the overall GC design in the latest Z Garbage Collector (ZGC), the previous simple classification methods like YoungGC and FullGC are no longer applicable. ZGC is mapped separately as follows.

Garbage collector name

Gen value

ZGC Cycles

cycles

ZGC Pauses

pauses

ZGC Minor Cycles

young_cycles

ZGC Minor Pauses

young_pauses

ZGC Major Cycles

old_cycles

ZGC Major Pauses

old_pauses

Note that the ARMS console displays a chart called "Thread Stack Usage," as shown in the figure below. This metric is not collected on the ARMS agent; it is calculated by multiplying the current number of live threads by 1MB. By default, the JVM allocates 1MB of space for each thread to store information such as the local variable table, operand stack, dynamic links, and method return addresses within stack frames.

image.png

Thread metrics

The ARMS agent has a scheduled task that periodically calls the JDK interface java.lang.management.ManagementFactory#getThreadMXBean to obtain thread metrics.

This method returns an instance of type java.lang.management.ThreadMXBean, which reflects the current JVM thread situation. The following code snippet demonstrates how to use this method.

public static void printThreads() {
    ThreadMXBean threadMXBean = java.lang.management.ManagementFactory.getThreadMXBean();
    int threadCount = threadMXBean.getThreadCount();
    int daemonThreadCount = threadMXBean.getDaemonThreadCount();
    long totalStartedThreadCount = threadMXBean.getTotalStartedThreadCount();
    long terminatedThreadCount = totalStartedThreadCount - threadCount;
    System.out.printf("allStartedThreadCount=%d\tcurrentThreadCount=%d\tdaemonThreadCount=%d\tterminatedThreadCount=%d\n"
            , totalStartedThreadCount, threadCount, daemonThreadCount, terminatedThreadCount);
}

The output of this code snippet may vary across different JVM versions. A possible output is shown as follows, which includes the cumulative number of threads started, the number of live threads, the number of daemon threads, and the cumulative number of terminated threads in the current JVM. Noted that, except for the cumulative number of terminated threads, the other thread counts are obtained directly by calling the ThreadMXBean method. The cumulative number of terminated threads is calculated by subtracting the current number of live threads from the cumulative number of threads started, representing the total number of threads that have completed their tasks and been terminated since the JVM was launched.

allStartedThreadCount=5	currentThreadCount=5	daemonThreadCount=4	terminatedThreadCount=0

Additionally, for the number of currently live threads, the agent will separately count the number of threads in each of the following states: RUNNABLE, BLOCKED, WAITING, and TIMED_WAITING.

The ARMS agent periodically collects this data, and after collection, it directly records these metrics without any additional processing, as detailed in the following table.

Metric

Description

arms_jvm_threads_count

The initial memory size.

The different threads mentioned above are distinguished by the following key dimensions.

Dimension

Description

Example

state

The thread status.

  • live: the number of live threads.

  • daemon: the number of daemon threads

  • terminated: the number of terminated threads. This is supported only by the ARMS agent 4.x.

For live threads, the following different states are counted separately.

  • new: New state

  • runnable: Runnable state

  • blocked: Blocked state

  • wait: Waiting state

  • timed-wait: Timed waiting state

Class metrics

The ARMS agent has a scheduled task that periodically calls the JDK interface ManagementFactory.getClassLoadingMXBean() to obtain class loading metrics.

This method returns an instance of type java.lang.management.ClassLoadingMXBean, which reflects the current JVM class situation. The following code snippet demonstrates how to use this method.

public static void printCurrentJVMMemoryUsage() {
    ClassLoadingMXBean classLoaderMXBean = ManagementFactory.getClassLoadingMXBean();
    long totalLoadedClassCount = classLoaderMXBean.getTotalLoadedClassCount();
    long unloadedClassCount = classLoaderMXBean.getUnloadedClassCount();
    System.out.printf("totalLoadedClassCount=%d\tunloadedClassCount=%d\n"
            , totalLoadedClassCount, unloadedClassCount);
}

The output of this code snippet may vary across different JVM versions. A possible output is shown as follows, which includes the cumulative number of classes loaded and the cumulative number of classes unloaded by the current JVM.

totalLoadedClassCount=1355	unloadedClassCount=0

Note that, since this data records cumulative values since the JVM was started, after periodically collecting this data, the ARMS agent subtracts the value obtained from previous collection to calculate the number of classes loaded and unloaded within the current period (default 15 seconds). It then reports and records these metrics as described in the following table.

Metric

Description

arms_class_load_loaded

The number of classes loaded in the current cycle.

arms_class_load_un_loaded

The number of classes unloaded in the current cycle.

File descriptor metrics

The ARMS agent has a scheduled task that periodically calls the JDK interface ManagementFactory.getOperatingSystemMXBean() to obtain file descriptor metrics.

This method returns an instance of type java.lang.management.OperatingSystemMXBean, which reflects the open file descriptor of the current JVM. The following code snippet demonstrates how to use this method.

public static void printFDUsage() {
    OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
    if (!(operatingSystemMXBean instanceof UnixOperatingSystemMXBean)) {
        return;
    }
    long openFDCount = ((UnixOperatingSystemMXBean) operatingSystemMXBean).getOpenFileDescriptorCount();
    long maxFDCount = ((UnixOperatingSystemMXBean) operatingSystemMXBean).getMaxFileDescriptorCount();
    System.out.printf("openFDCount=%d\tfdOpenRatio=%f\n"
            , openFDCount, (double) openFDCount / maxFDCount);
}

The output of this code snippet may vary across different JVM versions. A possible output is shown as follows, which includes the number of open file descriptors and the file descriptor open rate for the current JVM. The file descriptor open rate is calculated by dividing the number of currently open file descriptors by the total number of file descriptors that the current JVM can open.

openFDCount=184	fdOpenRatio=0.017969

The ARMS agent periodically collects this data, and after collection, it directly records these metrics without any additional processing, as detailed in the following table.

Metric

Description

arms_file_desc_open_count

The number of file descriptors opened by the current JVM.

arms_file_desc_open_ratio

The number of classes unloaded in the current cycle.