13 Printing Event Stack Trace
The example StackTraceSample.java
prints information
about an event's stack trace.
StackTraceSample
uses the Event Streaming API (see Monitor Events with Flight Recorder Event Streaming API) to print stack trace information of WithStackTrace
events. The sample recursively calls the method firstFunc
six times.
This method creates an event named WithStackTrace
. Every time an
WithStackTrace
occurs, information about the event's stack trace is
printed.
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);
}
}
The example StackTraceSample
prints output similar to the
following:
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
An event's stack trace, an instance of RecordedStackTrace, consists of a list of RecordedFrame instances. You can obtain the following information from a RecordedFrame with these methods:
- getMethod(): Returns the method from which the event was run.
- getLineNumber(): Returns the line number from which the event was run.
- isJavaFrame(): Indicates whether the RecordedFrame is a Java frame.
- getBytecodeIndex(): Returns the bytecode index from which the event was run.
- getType(): Returs the frame type; possible values
include
Interpreted
,JIT compiled
, andInlined
.
Flight Recorder uses a default stack depth of 64 method calls, which is more
than enough for this example. You can change this with the stackdepth
command-line option:
-XX:FlightRecorderOptions:stackdepth=depth
Note that values greater than 64 could create significant overhead and reduce performance.