Visit Azul.com Support

Azul Platform Prime MXBeans

See "Zing MXBeans" for complete summaries of interfaces, classes, methods, descriptions of parameters and return values generated from the source code.

Introduction

Azul Platform Prime MXBeans provide an interface to answer detailed questions about the behavior of your application and the Azul Zing Builds of OpenJDK (Zing). The MXBeans are designed for both monitoring performance and extracting the low level details to discover the root causes of problems. To use Azul Platform Prime MXBeans, you will need to use the command-line option:

 
-XX:+UseZingMXBeans

In order to compile code that relies on the use of Azul Platform Prime MXBeans, you will need to add the command line option to Zing javac command:

 
-J-XX:+UseZingMXBeans

You can compile code that relies on Azul Platform Prime MXBeans with a javac from another vendor. However, you will need to add the ZingJMM.jar file to the classpath. For example:

 
javac -cp $(ZINGMXBEANSJMMJARFULLPATH) $(JAVA_SOURCE_FILES)

Where the ZingJMM.jar file is at the following location, but can be copied to any convenient location for building your application:

 
$JAVA_HOME/etc/extensions/mxbeans/agents/ZingJMM.jar

Note that Azul Platform Prime MXBeans .jar file should not be added to the CLASSPATH variable. Otherwise, ZingMXBeans methods return an exception when called.

A program that is able to access the MXBeans and graph the collected metrics, such as JConsole, will aid in your ability to quickly understand the interfaces and their use. The available MXBean operations provide control of both the data collection and the JVM behavior.

See ZingGCReporter for details of using Azul Platform Prime MXBeans when running on Zing.

Note that you might get an error message when permissions are insufficient to access the MBean server. If that’s the case, you will need to create or update a ~/.java.policy file and add the required permissions to it (see table below). When using a .java.policy file, ensure that you have an entry policy.url.2=file:${user.home}/.java.policy in the $JAVA_HOME/jre/lib/security/java.security file.

Azul Platform Prime MXBeans provide the interfaces that enable you to get the answers you need to understand your application’s performance. Flexibility in the management of the values stored as peak values and those available in accumulators makes it easy to tailor the collection of the data for efficiency and effectiveness.

Azul Platform Prime MXBeans Interfaces

The Azul Platform Prime MXBeans in the table below are classified by their interface functionality.

Interface Summary Interface Description

GarbageCollectorMXBean

GarbageCollectorMXBean is an interface used by the management system to access garbage collector properties and reset the values of associated counter and accumulator properties.

MemoryManagerMXBean

MemoryManagerMXBean is an interface used by the management system to access memory manager properties.

MemoryMXBean

MemoryMXBean is an interface used by the management system to access memory-related properties. The MemoryMXBean interface is the easiest to use to answer your questions about Java heap use and performance.

MemoryPoolMXBean

MemoryPoolMXBean is an interface used by the management system to access memory pool properties.

PersistentProfileMXBean

PersistentProfileMXBean provides access to the reporting capabilities of ReadyNow profile logs.

TimeMXBean

Time provides the elapsed time since the launch of Zing and the clock time in milliseconds at the launch of Zing.

CompilationMXBean

CompilationMXBean provides information on compilation activity, including the total number of enqueued and in-progress compilations, and the total number of tier 1 and tier 2 compilations.

PersistentProfileMXBean

PersistentProfileMXBean is used to evaluate the ratio of matched and unmatched classes to the number of classes found in a profile log.

Azul Platform Prime MXBeans Classes

The Azul Platform Prime MXBeans classes are listed in the table below.

Class Summary Class Description

GarbageCollectorNotificationInfo

Garbage collector notification information.

GCDetails

A snapshot of the details of the JVM environment before and after a garbage collection.

ManagementFactory

The factory for retrieving all managed objects for the JVM as well as the JVM’s MBean server.

ManagementPermission

A SecurityPermission for use with the management system.

MemoryNotificationInfo

Memory notification information.

MemoryPoolNotificationInfo

Memory pool notification information.

MemoryUsage

A memory pool usage snapshot with sizes and the time the snapshot was taken.

PauseDetails

A PauseDetails object represents a pause event impacting all the threads in a running Java virtual machine and includes a timestamp specifying the time since the launch of the Java virtual machine process, the duration of the pause, and the reason for the pause (plus additional, optional, very detailed information).

Azul Platform Prime MXBeans Enums

The Azul Platform Prime MXBeans enumerations are listed in the table below.

Class Summary Class Description

MemoryPoolSizeType

For each memory pool: Characteristic of its size: FIXED or ELASTIC; otherwise: UNINITIALIZED.

MemoryType

For each memory pool: in the Zing process: JAVA_HEAP or NON_JAVA_HEAP; for system memory: SYSTEM.

Refer to the Azul Platform Prime MXBeans javadoc for more information about the MXBeans APIs.

Monitoring Zing Using JMX With Azul Platform Prime MXBeans

For those cases where you want to monitor Zing in addition to monitoring the application, use Azul Platform Prime MXBeans.

Primarily, the following are of interest for Zing monitoring:

  • Java heap memory use

  • Garbage collector activity: concurrent GC time and application stopped time

For accessing the values for each of these attributes over time, use any JMX-capable systems monitoring tool or $JAVA_HOME/bin/jconsole. In JConsole, use the entries in its MBeans tab to access the Azul Platform Prime MXBeans and get a quick overview.

Java Heap Memory Use

Monitoring memory use is helpful to detect memory leaks or to collect statistics about the general memory use by an application. The latter can be used to correctly size the Java heap to be consistent with the application’s memory requirements.

MXBean: com.azul.zing → Memory → Attributes:

  • PercentJavaHeapOccupiedAfterCollection: The percentage of the heap in use after each garbage collection. The returned value is equivalent to the application’s current minimum memory requirement. It can also be used to detect memory leaks because consistently increasing values after full garbage collections create an easily seen pattern. It’s useful to set a warning threshold that triggers an alarm if the value exceeds 70% over a 5-minute interval, (though this threshold value depends on the live set size in use by your application). The value includes the memory in use for the Permanent Generation, a memory pool in Zing’s Java heap.

  • ApplicationObjectHeapUse and ApplicationObjectHeapUsableMemory: The process’s current memory use and the total size of the application object area of the Java heap. The returned heap use value represents the current memory use of the New (also called Young) Generation together with the current memory use of the Old Generation. This metric is a refinement of the PercentJavaHeapOccupiedAfterCollection that removes some of the guesswork about the contributions of the other memory pools in Zing’s Java heap to the application’s Java heap memory use.

MXBean: java.lang → Memory → Attributes:

  • HeapMemoryUsage (init, used, committed, max). Used for monitoring memory use by JVMs. For JVMs other than Zing, setting notification * thresholds can help monitor the JVM and application’s use of system resources. When using Zing, the Java heap use between collections varies between a minimum of the live set size and 100% (or more). In other words, Zing attempts to use a much of the Java heap as possible. Doing so extends the time between collections and lowers the Zing garbage collector’s overhead. Using a maximum use notification threshold value when running an application with Zing that is less than 100% will result in spurious notifications.

Garbage Collector Activity

Monitoring garbage collector activity is useful for capacity planning. For instance, the activity level can be used to determine the CPU resources required to process varying application object allocation rates. Because that object allocation rate is proportional to the amount of work done by the application, the garbage collector activity can be used to determine maximum application workloads. Naturally, the Java heap size is related to garbage collector activity. Increasing the Java heap size can reduce the impact of sudden high garbage collector activity and the underlying high workloads. The latter are also seen as allocation rate spikes.

MXBean: com.azul.zing → GarbageCollector → GPGC New → Attributes:

  • PercentageOfTimeCollectorIsRunning: The ratio of the "garbage collection time" to the "interval between end times of two consecutive collections.” The value is based on the most recent garbage collection and is not cumulative. The percentages are calculated separately for the New Generation collector and the Old Generation collector. A warning threshold of 30% over 5 minutes should be set to warn about over-use of available CPU resources by the garbage collector. This is most important metric for monitoring Zing’s garbage collector behavior because this metric is the first to increase in situations when the system’s capacity is nearing its limits.

MXBean: com.azul.zing → GarbageCollector → GPGC Old → Attributes:

  • PercentageOfTimeCollectorIsRunning: The same recommendations as for the New Generation collector, but for the Old Generation collector. Use the same threshold to monitor. The time for processing Permanent Generation objects is included in this metric.

If you need more fine-granular monitoring, the following additional attributes provide more precise information about the garbage collectors’ behavior:

  • CollectorCumulativePauseTimeSec: Cumulative garbage collector pause time. The typical length of time for each of these Zing pauses is in the range of single digit milliseconds or less.

  • CollectorCumulativeRunningTimeSec: Cumulative wall clock time Zing’s garbage collector has been running in parallel with the application’s threads. During this time, more CPU resources are used because the garbage collector is running its own set of threads. The number of running garbage collector threads (for each of the New Generation collector and Old Generation collector) is based on the number of CPU threads (hyper-threads or just physical cores if the machine is configured with hyper-threading off).

  • CollectionCount: Cumulative number of garbage collections since Zing start.

MXBean: com.azul.zing → Time → Attributes:

  • ElapsedTimeSinceJVMStartSec: Seconds since Zing start. Useful for time-base calculations with CollectorCumulativePauseTimeSec and CollectorCumulativeRunningTimeSec.

Code Cache Memory Use

MXBean: com.azul.zing > MemoryPool > CodeCache → Attributes:

  • CurrentUse: Use of the memory pool where JIT-compiled code is stored. Useful to decide whether increasing the size of the code cache using -XX:ReservedCodeCacheSize=N (the default value is 10% of Xmx) is needed.

  • CurrentSize: Value returned is the maximum size of the code cache. The value can be set by using -XX:ReservedCodeCacheSize=N (the default value is 10% of Xmx).

Configuration

To activate the JMX connector on Zing and enable the Azul Platform Prime specific MXBeans, add the following command line parameters and configure them according to your system’s requirements (port and security options):

 
-XX:+UseZingMXBeans -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9001 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=passwordFile -Dcom.sun.management.jmxremote.ssl=false

The passwordFile contains two lines with username and associated password for read only access to attributes (monitorRole) and read/write access to methods and user functions (controlRole). Only change the passwords, not the usernames! Example:

 
monitorRole password1 controlRole password2

File permission to the passwordFile needs to be limited:

 
chmod og-rwx passwordFile

To avoid connection failures over the JMX protocol on systems with multiple network interfaces or to connect to a container system, it is often needed to specify the RMI hostname and RMI port:

 
-Djava.rmi.server.hostname=HOSTNAME -Dcom.sun.management.jmxremote.rmi.port=9001

Where:

  • for the RMI port, the same number as for the JMX port can be used

  • for HOSTNAME, enter the IP address or hostname you would later use on the client side to connect to

To improve security, please enable com.sun.management.jmxremote.ssl=true.

Monitoring for Readiness Without Extra Dependencies

One of the factors that define if an application is ready to handle traffic or load is the number of compile queues that still need to be handled. When this value falls below a certain treshold (depending on your use case), you can consider the application to be warmed-up enough to receive traffic.

With Zing, you may want to access its proprietary MXBeans - for example, the com.azul.zing:type=Compilation MXBean - to gather runtime metrics or perform advanced monitoring. Typically, this requires you to add the relevant Zing-specific MXBean classes to your classpath to compile your code. You can find this in $JAVA_HOME/etc/extensions/mxbeans/agents/ZingJMM.jar.

However, if you build a custom load balancer (or any tool interacting with Zing) and want to avoid compile-time dependencies on Azul-specific libraries, you can use a simpler approach. Instead of importing and referencing the Zing MXBean interface directly, you can access the bean using its ObjectName:

 
ObjectName beanName = new ObjectName("com.azul.zing:type=Compilation");

With this approach, you can query and interact with the MXBean dynamically via JMX, assuming it is available at runtime. As long as Zing is started with the MXBean enabled with -XX:+UseZingMXBeans, the corresponding class will be loaded into the JVM’s internal classloader.

This is a basic example implementation to get the total outstanding compiles:

 
import java.lang.management.ManagementFactory; import javax.management.InstanceNotFoundException; import javax.management.MBeanServerConnection; import javax.management.ObjectName; public class Main { public static void main(String[] args) { MBeanServerConnection mbs = ManagementFactory.getPlatformMBeanServer(); try { ObjectName beanName = new ObjectName("com.azul.zing:type=Compilation"); Long queueDepth = (Long) mbs.getAttribute(beanName, "TotalOutstandingCompiles"); System.out.println("Queue depth: " + queueDepth); } catch (InstanceNotFoundException e) { System.out.println("Not running on Zing," + " or running Zing without -XX:+UseZingMXBeans"); } catch (Exception e) { // something else is wrong, this is unexpected e.printStackTrace(); } } }

This is a more extended example that shows the time needed to reach an empty compile queue:

 
import java.lang.management.*; import javax.management.*; /** * A utility for Azul Zing JVMs, useful for awaiting the draining of JIT compilation * queues at program start. This utility may be used by e.g. startup or readiness * probes to have code better optimized before traffic actually starts. * * compileQueueDepthOrDeadlineReached(targetDepth, deadlineSinceStartMs) * → true if (TotalOutstandingCompiles ≤ targetDepth) OR * (uptime ≥ deadlineSinceStartMs) * → false otherwise. * * The demo main() can be used as an example. */ public final class ZingAwaitCompilationsOnStart { private static final long JVM_START = ManagementFactory.getRuntimeMXBean().getStartTime(); private static final MBeanServer MBS = ManagementFactory.getPlatformMBeanServer(); private static final boolean IS_ZING = System.getProperty("java.vm.name", "") .toLowerCase().contains("zing"); private static final ObjectName COMPILATION_OBJECTNAME; private static final boolean COMPILATION_MXBEAN_AVAILABLE; static { ObjectName objectName = null; boolean mxbeanAvailable = false; if (IS_ZING) { try { objectName = new ObjectName("com.azul.zing:type=Compilation"); mxbeanAvailable = MBS.isRegistered(objectName); } catch (MalformedObjectNameException e) { e.printStackTrace(System.err); } } COMPILATION_OBJECTNAME = objectName; COMPILATION_MXBEAN_AVAILABLE = mxbeanAvailable; } private ZingAwaitCompilationsOnStart() {} /** * @param targetDepth queue size (inclusive) that satisfies the condition * @param deadlineSinceStartMs absolute deadline counted from JVM start (ms) * @param awaitDeadlineOnlyOnZing true → on non-Zing JVMs return <code>true</code> immediately */ public static boolean compileQueueDepthOrDeadlineReached(int targetDepth, long deadlineSinceStartMs, boolean awaitDeadlineOnlyOnZing) { if (System.currentTimeMillis() - JVM_START >= deadlineSinceStartMs) { return true; } if (!IS_ZING) { return awaitDeadlineOnlyOnZing; // if true, succeed immediately on non-Zing } if (!COMPILATION_MXBEAN_AVAILABLE) { return false; } try { long outstandingCompiles = ((Number) MBS.getAttribute( COMPILATION_OBJECTNAME, "TotalOutstandingCompiles")).longValue(); return outstandingCompiles <= targetDepth; } catch (Exception e) { return false; } } public static void main(String[] args) { int targetDepth = 0; // wait until the queue empties long deadlineMs = 120_000; // 120 s from JVM start long startSinceStart = System.currentTimeMillis() - JVM_START; System.out.println("Await loop started at JVM-uptime(ms): " + startSinceStart); while (!compileQueueDepthOrDeadlineReached(targetDepth, deadlineMs, true)) { try { Thread.sleep(1); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return; } } long endSinceStart = System.currentTimeMillis() - JVM_START; System.out.println("Condition met at JVM-uptime(ms): " + endSinceStart); } }