Summary
Add the annotation class jdk.jfr.Throttle to indicate that an event should be rate-limited.
Problem
The JDK Flight Recorder (JFR) currently offers two methods for preventing an excessive number of events: 1) disabling the event, or 2) setting a threshold.
1) The threshold setting only records events that exceed a minimum duration, which doesn't work for events that lack a duration, such as those events that represent an instant, for example, exception events. As a result, certain high-frequency instant events must be turned off by default to prevent excessive CPU usage or flooding of JFR buffers, which can cause other, more important events to be lost.
2) Examples of the second category are the jdk.SocketRead and jdk.SocketWrite events, the duration of which depends on the program, for example, the number of users currently using a web application. Therefore, the default threshold must be very high to prevent high CPU usage or flooding. Today, these socket events use a 20-ms threshold, which is high and therefore only reflects extreme outliers.
Solution
Throttling, i.e., rate-limiting, allows for statistical sampling without the risk of flooding the system. The data recorded is more representative because it not only reflects extreme outliers.
Introduce a Throttle annotation for JDK events and user-defined events. The Throttle annotation has existed since JDK 16, but it is located in an internal package, unavailable to end users, and is only made available for HotSpot events. Users can specify a rate, expressed as the number of events per time unit, for example, "1000/s". The annotation will be off by default.
The throttle option can be combined with the threshold option to record all socket events that take more than 1 ms, but never more than 500 events per second.
Specification
/**
* Event annotation, specifies the maximum rate of events per time unit, (for
* example, {@code "100/s"}).
* <p>
* If the event class annotated with {@code Throttle} are filtering by other
* settings, such as a {@link jdk.jfr.Threshold} or a user-defined setting, the
* throttling will happen after those settings have been applied.
*
* @since 25
*/
@MetadataDefinition
@Target({ ElementType.TYPE })
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Throttle {
/**
* Setting name {@code "throttle"} for configuring throttled events.
*/
public static final String NAME = "throttle";
/**
* The throttle rate, for example {@code "100/s"}.
* <p>
* String representation of a non-negative {@code long} value followed by a
* forward slash ("/") and one of the following units: <br>
* <ul style="list-style-type:none">
* <li>{@code "ns"} (nanoseconds)</li>
* <li>{@code "us"} (microseconds)</li>
* <li>{@code "ms"} (milliseconds)</li>
* <li>{@code "s"} (seconds)</li>
* <li>{@code "m"} (minutes)</li>
* <li>{@code "h"} (hours)</li>
* <li>{@code "d"} (days)</li>
* </ul>
* <p>
* Example values, {@code "6000/m"}, {@code "10/ms"} and {@code "200/s"}.
* <p>
* Specifying zero, for example {@code "0/s"}, results in no events being
* emitted.
* <p>
* Specifying {@code "off"} (case-sensitive) results in all events being emitted.
*
* @return the throttle value, default {@code "off"} not {@code null}
*/
String value() default "off";
}
- csr of
-
JDK-8351594 JFR: Rate-limited sampling of Java events
-
- Resolved
-