Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

JVM performance monitoring with JMC agent

November 16, 2021
Joshua Matsuoka
Related topics:
JavaKubernetesOpen source
Related products:
Red Hat OpenShift

Share:

    With the recent JDK Mission Control (JMC) 8.1 release, now is a good time to look at the new JMC agent plugin. The plugin, which was merged upstream, provides a convenient way to add custom JDK Flight Recorder (JFR) events to a running Java virtual machine (JVM) without restarting or rebuilding the Java application.

    JDK Mission Control and JDK Flight Recorder

    Monitoring Java application performance in a production environment can be costly, even more so in environments where restarting the JVM to install monitoring capabilities is unfeasible or undesirable. JDK Flight Recorder (JFR) is a Java application monitoring solution built into the JVM that offers minimal performance overhead and setup.

    Note: Do you need to be able to retrieve, store, and analyze flight recordings from containerized JVMs? Check out Cryostat 2.0—JDK Flight Recorder for containers.   

    JMC agent

    JMC agent is a tool being developed alongside JDK Mission Control to inject custom JDK Flight Recorder events at runtime without needing to restart the JVM. The agent works by injecting bytecode for custom JDK Flight Recorder events, as well as the bytecode to emit them within specified methods. JMC agent is also able to capture the values of method parameters and class fields and emit them as part of custom events. JDK Mission Control 8.1 includes a plugin for controlling the agent throughout its lifecycle.

    Limitations of JMC agent

    JMC agent has a few limitations that developers should be aware of:

    • It doesn't work with synthetic classes.
    • It is also unable to access nestmates' private fields.
    • Newly uploaded configurations work only with classes defined with the system class loader.

    How to get the JMC agent plugin

    Because the JMC agent plugin is now part of upstream JDK Mission Control 8.1, you may simply download and run it to start using it. The agent plugin requires the JMC agent JAR, as well. You can download the JDK Mission Control 8.1.0 and JMC agent JAR from the jmc-overrides GitHub page of the Eclipse Adoptium Working Group.

    Using the JMC agent plugin

    To illustrate the use of the JMC agent plugin with an example, consider a program that reads words from a webpage, does analysis on them, and stores them in a database. A couple of sample methods follow:

        private static void loadWords(String path) {
    
                try {
    
                    List<String> lines = retrieveWords(path);
    
                    for (String line : lines) {
    
                        for (String word : Arrays.asList(line.split(" "))) {
    
                                doWork(word);
    
                                storeWord(word);
    
                        }
    
                    }
    
                } catch (Exception e) {
    
                    e.printStackTrace();
    
                    System.err.println(e.getMessage());
    
                }
    
        }
    
        private static void storeWord(String word) {
    
                Jedis jedis = pool.getResource();
    
                jedis.sadd(key, word);
    
                pool.returnResource(jedis);
    
        }

    For this article, we want to instrument the storeWord method with a custom event and capture the word passed to it as its parameter. To do this without the agent, we would need to create our own custom event class, add the code to emit the class to the function, then recompile and restart the application. In a production environment, this is costly and potentially unfeasible. Using the agent, however, we can do it with minimal intrusion.

    When you start JDK Mission Control, the agent plugin will be available under the JVM browser. Simply find the JVM you wish to instrument and select the agent option, as shown in Figure 1. You will be prompted for the agent's JAR file and an optional XML file with a probe definition to load. This XML file is optional because the agent plugin has wizards to guide the creation process and remove the need to manually write the XML.

    The JVM browser offers a page where you provide the agent JAR and an optional XML configuration.
    Figure 1. The JVM browser offers a page where you provide the agent JAR and an optional XML configuration.

    After you supply the agent JAR, you are taken to the landing page for the agent plugin, shown in Figure 2. The page displays the currently active injected events, if any, and the currently active agent configuration.

    The agent plugin's landing page, currently empty, lists configurations and events.
    Figure 2. The agent plugin's landing page, currently empty, lists configurations and events.

    On this page, you can save the currently active probes and configurations as a preset for later use, using the save icon in the top right corner of the page. Alternatively, load a configuration via the load icon.

    Configuring JMC agent in the preset manager

    Another way to create presets is by using the preset manager, which is located under the window menu. This preset manager lets you not only create new presets from existing configurations, but also create new presets from a set of wizards to guide the process.

    The first page that appears when you use the preset manager is the configuration options for the agent, shown in Figure 3. You can use these options to define the prefix used for any generated event classes, as well as whether the agent is allowed to call toString methods and use converters. These are advanced functionality, enabling the capture of method parameters, return values, and fields.

    The Edit Preset Global Configurations page controls the use of advanced features for all events.
    Figure 3. The Edit Preset Global Configurations page controls the use of advanced features for all events.

    Defining custom events

    From here, you can begin defining the custom events you want to inject. Begin by defining the name and description of the custom event, as well as the class and method you want to instrument with it, as shown in Figure 4. Provide a fully qualified name as the class name, and the method descriptor for the method being instrumented.

    The Edit Event Configurations page configures a specific event.
    Figure 4. Use the Edit Event Configurations page to configure a specific event.

    The method descriptor takes the form of (Parameter Descriptor*)Return Descriptor. For example, for the method void storeWord(String word), the method descriptor would be (Ljava/lang/String;)V. See the JVM specification for more information about the method descriptor format.

    Additional options control whether to record stack traces and exceptions, as well as where to inject events (such as the beginning of the method or its end). In this case, we’ll inject the event at the start.

    Capturing event parameters and fields

    Following this page are additional wizards for capturing parameters, and for returning the values of the instrumented methods as well as fields within the class being instrumented, as shown in Figure 5. To capture the parameter we’re interested in, we need to provide the index of the parameter and whether it is a return value. In this case, since it’s the first and only parameter, it has the index 0.

    The "Edit a Parameter or Return Value" page controls access to specific parts of a method.
    Figure 5. Use the Edit a Parameter or Return Value page to control access to specific parts of a method.

    When you’re done creating events and capturing parameters and fields, the agent plugin provides a preview of the completed XML configuration, as shown in Figure 6. Once finished, the configuration can be loaded into the target JVM, and JDK Mission Control can then be used to start a flight recording with the newly created events.

    The Preview Preset Output page shows the XML configuration automatically generated from your specifications on previous pages.
    Figure 6. The Preview Preset Output page shows the XML configuration automatically generated from your specifications.

    Once the preset is complete and has been loaded in, the events and configuration options are displayed on the agent plugin's status page, shown in Figure 7.

    The agent plugin's status page shows the parameters you configured.
    Figure 7. The agent plugin's status page shows the parameters you configured.

    Conclusion

    Together, JDK Flight Recorder, JDK Mission Control, and JMC agent provide a powerful set of tools for monitoring and diagnosing JVM performance. These tools work in an unobtrusive manner with minimal performance overhead. The agent plugin further builds on these tools and provides an easy way to inject custom flight recorder events into the JVM at runtime without needing to restart it, which can be a lengthy and expensive process in a production environment.

    Although there are alternatives to JMC agent, such as Byteman, they are often suited for much more general uses. The JMC agent and agent plugin are designed for creating and injecting JDK Flight Recorder events, making them better suited for these purposes. With the release of JDK Mission Control 8.1, the agent plugin is now provided out of the box, making it easier than ever to take advantage of these tools for any performance monitoring needs.

    The JMC agent and agent plugin are both still in development. To keep up to date with these developments and provide ideas and feedback, feel free to join the jmc-dev mailing list and track development in the upstream GitHub repository.

    Last updated: September 20, 2023

    Related Posts

    • Collect JDK Flight Recorder events at runtime with JMC Agent

    • Set up JDK Mission Control with Red Hat Build of OpenJDK

    • Get started with JDK Flight Recorder in OpenJDK 8u

    • Announcing Cryostat 2.0: JDK Flight Recorder for containers

    Recent Posts

    • Cloud bursting with confidential containers on OpenShift

    • Reach native speed with MacOS llama.cpp container inference

    • A deep dive into Apache Kafka's KRaft protocol

    • Staying ahead of artificial intelligence threats

    • Strengthen privacy and security with encrypted DNS in RHEL

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue