12 定期イベント
PeriodicSample.javaの例では、作成されて開始されたスレッドの合計数を1秒ごとに記録するStartedThreadCountという名前の定期イベントが作成されます。
               
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import jdk.jfr.Event;
import jdk.jfr.FlightRecorder;
import jdk.jfr.Label;
import jdk.jfr.Name;
import jdk.jfr.Period;
public class PeriodicSample {
    private static ThreadMXBean tBean =
        ManagementFactory.getThreadMXBean();
    @Name("com.oracle.StartedThreadCount")
    @Label("Total number of started threads")
    @Period("1 s")
    static class StartedThreadCount extends Event {
        long totalStartedThreadCount;
    }
    public static void main(String[] args) throws InterruptedException {
        Runnable hook = () -> {
            StartedThreadCount event = new StartedThreadCount();
            event.totalStartedThreadCount =
                tBean.getTotalStartedThreadCount();
            event.commit();
        };
        FlightRecorder.addPeriodicEvent(StartedThreadCount.class, hook);
        for (int i = 0; i < 4; i++) {
            Thread.sleep(1500);
            Thread t = new Thread();
            t.start();
        }
      
        FlightRecorder.removePeriodicEvent(hook);
    }
}次のコマンドを使用して、PeriodicSampleを実行します:
               
java -XX:StartFlightRecording:filename=periodic.jfr PeriodicSample.java
jfr print --events StartedThreadCount periodic.jfr 最後のコマンドでは、次のような出力が表示されます:
com.oracle.StartedThreadCount {
  startTime = 00:59:40.769
  totalStartedThreadCount = 12
    ...
}
com.oracle.StartedThreadCount {
  startTime = 00:59:41.816
  totalStartedThreadCount = 12
    ...
}
com.oracle.StartedThreadCount {
  startTime = 00:59:42.866
  totalStartedThreadCount = 13
    ...
}
com.oracle.StartedThreadCount {
  startTime = 00:59:43.918
  totalStartedThreadCount = 14
    ...
}
com.oracle.StartedThreadCount {
  startTime = 00:59:44.962
  totalStartedThreadCount = 14
    ...
}定期イベントを作成するには、次の2つのステップを実行します:
- @Period注釈を使用してイベントを発行する頻度を指定します:
@Name("com.oracle.StartedThreadCount") @Label("Total number of started threads") @Period("1 s") static class StartedThreadCount extends Event { long totalStartedThreadCount; }期間の有効な単位は、
ns、us、ms、s、m、hおよびdです。また、次のいすれかを指定することも可能です:
everyChunk: 定期イベントは記録中に少なくとも1回発行されます。beginChunk: 定期イベントは記録の開始時に発行されます。endChunk: 定期イベントは記録の終了時に発行されます。
 - FlightRecorder.addPeriodicEvent(Class<? extends Event>, Runnable)静的メソッドを使用して、定期イベントを追加します。1つ目の引数は、定期イベントのクラス名です。2つ目の引数はコールバック・メソッドで、イベントを作成してコミットするラムダ式で表されています。
Runnable hook = () -> { StartedThreadCount event = new StartedThreadCount(); event.totalStartedThreadCount = tBean.getTotalStartedThreadCount(); event.commit(); }; FlightRecorder.addPeriodicEvent(StartedThreadCount.class, hook); 
メソッドFlightRecorder.removePeriodicEvent(Runnable)は、定期イベントに関連付けられているラムダ式を削除します。ほとんどの場合、このメソッドは必要ありません。Recording.disable(Class<? extends Event>)を呼び出せば、定期イベントを無効にできます。ただし、removePeriodicEventを呼び出す理由の1つは、メモリー・リークの回避です。たとえば、データのロードとアンロードが行われたアプリケーション・サーバーがあるとします。サーバーがロードしてアンロードしたデータをコールバック・メソッドが参照していると、そのデータのガベージ・コレクションが行われないことがあります。データがアンロードされるときにコールバック・メソッドを削除すれば、これを回避できます。