13 イベント・スタック・トレースの出力
StackTraceSample.java
の例では、イベントのスタック・トレースに関する情報が出力されます。
StackTraceSample
はイベント・ストリームAPI (「Flight Recorderイベント・ストリームAPIを使用したイベントの監視」を参照)を使用して、WithStackTrace
イベントのスタック・トレース情報を出力します。サンプルは、メソッドfirstFunc
を再帰的に6回呼び出します。このメソッドは、WithStackTrace
という名前のイベントを作成します。WithStackTrace
が発生するたびに、イベントのスタック・トレースに関する情報が出力されます。
import java.util.List;
import java.util.function.Consumer;
import jdk.jfr.Event;
import jdk.jfr.EventType;
import jdk.jfr.Label;
import jdk.jfr.Name;
import jdk.jfr.StackTrace;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordedFrame;
import jdk.jfr.consumer.RecordedStackTrace;
import jdk.jfr.consumer.RecordingStream;
public class StackTraceSample {
@Name("com.oracle.WithStackTrace")
@Label("With Stack Trace")
@StackTrace(true)
static class WithStackTrace extends Event {
String message;
}
public static void main(String... args) throws Exception {
Consumer<RecordedEvent> myCon = x -> {
EventType et = x.getEventType();
System.out.println("Label: " + et.getLabel());
System.out.println("Message: " + x.getValue("message"));
RecordedStackTrace rst = x.getStackTrace();
if (rst != null) {
List<RecordedFrame> frames = rst.getFrames();
System.out.println(
"Number of frames: " + frames.size());
for (RecordedFrame rf : frames) {
System.out.println("Method, line number: "
+ rf.getMethod().getName() + ", "
+ rf.getLineNumber());
}
}
System.out.println("");
};
try (RecordingStream rs = new RecordingStream()) {
rs.onEvent("com.oracle.WithStackTrace", myCon);
rs.startAsync();
firstFunc(5);
rs.awaitTermination();
}
}
static void firstFunc(int n) {
if (n > 0) {
secondFunc(n - 1);
}
WithStackTrace event = new WithStackTrace();
event.message = "n = " + n;
event.commit();
}
static void secondFunc(int n) {
firstFunc(n);
}
}
StackTraceSample
の例では、次のような出力が表示されます:
Label: With Stack Trace
Message: n = 0
Number of frames: 12
Method, line number: firstFunc, 97
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: main, 86
Label: With Stack Trace
Message: n = 1
Number of frames: 10
Method, line number: firstFunc, 97
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: main, 86
Label: With Stack Trace
Message: n = 2
Number of frames: 8
Method, line number: firstFunc, 97
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: main, 86
Label: With Stack Trace
Message: n = 3
Number of frames: 6
Method, line number: firstFunc, 97
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: main, 86
Label: With Stack Trace
Message: n = 4
Number of frames: 4
Method, line number: firstFunc, 97
Method, line number: secondFunc, 102
Method, line number: firstFunc, 93
Method, line number: main, 86
Label: With Stack Trace
Message: n = 5
Number of frames: 2
Method, line number: firstFunc, 97
Method, line number: main, 86
イベントのスタック・トレース(RecordedStackTraceのインスタンス)は、RecordedFrameインスタンスのリストで構成されています。下に示すメソッドを使用して、RecordedFrameから次の情報を取得できます:
- getMethod(): イベントの実行元のメソッドを返します。
- getLineNumber(): イベントの実行元の行番号を返します。
- isJavaFrame(): RecordedFrameがJavaフレームかどうかを示します。
- getBytecodeIndex(): イベントの実行元のバイトコード・インデックスを返します。
- getType(): フレーム・タイプを返します。使用される値は、
Interpreted
、JIT compiled
およびInlined
です。
Flight Recorderは、デフォルトのスタック深度が64メソッド呼出しで、この例では十二分です。これは、stackdepth
コマンド行オプションで次のようにして変更できます:
-XX:FlightRecorderOptions:stackdepth=depth
64よりも大きい値を指定すると、大量のオーバーヘッドが発生し、パフォーマンスが低下する可能性があることに注意してください。