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 EveryTwoSeconds periodicsample.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つは、メモリー・リークの回避です。たとえば、データのロードとアンロードが行われたアプリケーション・サーバーがあるとします。サーバーがロードしてアンロードしたデータをコールバック・メソッドが参照していると、そのデータのガベージ・コレクションが行われないことがあります。データがアンロードされるときにコールバック・メソッドを削除すれば、これを回避できます。