3.4. 定义并使用自定义事件 API

JDK Flight Recorder(JFR)是一个包括自定义事件 API 的事件记录器。存储在 jdk.jfr 模块中的自定义事件 API 是软件接口,使您的应用程序能够与 JFR 通信。

JFR API 包括可用于管理记录和为您的 Java 应用程序、JVM 或操作系统创建自定义事件的类。

在使用自定义事件 API 监控事件之前,您必须为自定义事件类型定义名称和元数据。

您可以通过扩展 Event 类来定义 JFR 基本事件,如 DurationInstantRequestable、Requestable 或 Time 事件。特别是,您可以将字段(如持续时间值)添加到与应用程序有效负载属性定义的数据类型匹配的类。定义 Event 类后,您可以创建事件对象。

此流程演示了如何通过 JFR 和 JDK Mission Control(JMC)使用自定义事件类型来分析简单示例程序的运行时性能。

流程

  1. 在您的自定义事件类型中,在 Event 类中,使用 @name 注释来命名自定义事件。这个名称显示在 JMC 图形用户界面(GUI)。

    Event 类中定义自定义事件类型名称示例

    @Name(“SampleCustomEvent”)
    public class SampleCustomEvent extends Event {...}

  2. 定义您的 事件 类及其属性的元数据,如 name、flavor 和 labels。标签显示客户端的事件类型,如 JMC。

    注意

    大型记录文件可能会导致性能问题,这可能会影响您要与文件交互的方式。请确定您正确定义您需要的事件记录注解数量。定义不必要的注解可能会增加记录文件的大小。

    为示例 事件 类定义注解示例

    @Name(“SampleCustomEvent”)  1
    @Label("Sample Custom Event")
    @Category("Sample events")
    @Description("Custom Event to demonstrate the Custom Events API")
    @StackTrace(false) 2
    public class SampleCustomEvent extends Event {
    
    
        @Label("Method") 3
        public String method;
    
    
        @Label("Generated Number")
        public int number;
    
    
        @Label("Size")
        @DataAmount 4
        public int size;
    }

    1
    Details 注解,如 @Name,它定义了自定义事件在 JMC GUI 中如何显示的元数据。
    2
    @StackTrace 注释会增加动态记录的大小。默认情况下,JFR 不包含为事件创建的位置的 stackTrace
    3
    @Label 注释定义每种方法的参数,如 HTTP 请求的资源方法。
    4
    @DataAmount 注释包含一个属性,用于定义数据量的字节数。JMC 其它单位会自动呈现数据量,如兆字节(MB)。
  3. 事件 类中定义上下文信息。此信息设置自定义事件类型的请求处理行为,以便您可以配置事件类型来收集特定的 JFR 数据。

    定义简单 类和事件循环示例

    public class Main {
    
    	private static int requestsSent;
    
    	public static void main(String[] args) {
        	// Register the custom event
        	FlightRecorder.register(SampleCustomEvent.class);
        	// Do some work to generate the events
        	while (requestsSent <= 1000) {
            	try {
                	eventLoopBody();
                	Thread.sleep(100);
            	} catch (Exception e) {
                	e.printStackTrace();
            	}
        	}
        }
    
    	private static void eventLoopBody() {
        	// Create and begin the event
        	SampleCustomEvent event = new SampleCustomEvent();
        	event.begin();
        	// Generate some data for the event
        	Random r = new Random();
        	int someData = r.nextInt(1000000);
        	// Set the event fields
        	event.method = "eventLoopBody";
        	event.number = someData;
        	event.size = 4;
        	// End the event
        	event.end();
        	event.commit();
        	requestsSent++;
        }

    在前面的示例中,简单 类注册事件,事件循环会填充事件字段,然后发出自定义事件。

  4. 在您选择的应用程序中检查事件类型,如 JMC 或 JFR 工具。

    图 3.2. 在 JMC 中检查事件类型示例

    检查事件类型示例应用程序

    JFR 记录可能包含不同的事件类型。您可以在应用程序中检查每个事件类型。

其他资源