As a developer, you can also create your own custom events using the JFR API and view and analyze them using MC. Here's an example; let's define a custom event:
class MyEvent extends Event { @Label("EventMessage") String message; }
Now let's modify the AThread class to use events, instead of printing to console:
class AThread implements Runnable { String name = "default"; private Random numGenerator = new Random(); private ArrayList<Double> list = new ArrayList<Double>(1000000); AThread(String name) { this.name = name; } public void run() { MyEvent event; for (int i = 0; i < 1000000; i++) { list.add(numGenerator.nextDouble()); event = new MyEvent(); event.message = "Allocated : " + name + "[" + i + "]"; event.commit(); } } } public class WithCustomEvents { public static void main(String... args) throws Exception { for (int i = 0; i < 500; i++) { new Thread(new AThread("Thread" + i)).start(); } } }
You can use the same command line options to execute your application, profiling it with JFR:
> java -XX:StartFlightRecording,filename=CustomEvents.jfr WithCustomEvents
Now, instead of using MC to view these events, you can create another application that reads the logged events from CustomEvents.jfr, as follows:
class ReadFRData { public static void main(String args[]) throws Exception { Path p = Paths.get("CustomEvents.jfr"); for (RecordedEvent e : RecordingFile.readAllEvents(p)) { System.out.println(e.getStartTime() + " : " + e.getValue("message")); } } }