{"id":370,"date":"2013-09-11T23:22:27","date_gmt":"2013-09-11T22:22:27","guid":{"rendered":"http:\/\/hirt.se\/blog\/?p=370"},"modified":"2013-09-13T17:47:13","modified_gmt":"2013-09-13T16:47:13","slug":"creating-flight-recordings","status":"publish","type":"post","link":"https:\/\/hirt.se\/blog\/?p=370","title":{"rendered":"Creating Flight Recordings"},"content":{"rendered":"<p><em>With the Hotspot JDK 7u40 there is a nifty new tool called <a href=\"http:\/\/oracle.com\/missioncontrol\">Java Mission Control<\/a>. Users of the nifty <strong>old <\/strong>tool <a href=\"http:\/\/www.oracle.com\/technetwork\/middleware\/jrockit\/mission-control\/index.html\">JRockit Mission Control<\/a> will recognize a lot of the features. This particular blog entry focuses on the Java Flight Recorder and various ways you can go about to create a flight recording.<\/em><\/p>\n<p>In the last <a href=\"https:\/\/hirt.se\/blog\/?p=364\">blog entry about the method profiler<\/a> I showed that Mission Control can be quite useful for profiling production systems. However, I only showed one way to produce the actual recording.<\/p>\n<p>There are several different ways to produce a recording, all of them useful in a certain context. But before we get into that, we should first discuss the two different kinds of recordings.<\/p>\n<h2>Continuous Recordings<\/h2>\n<p>Continuous recordings are not only very hard to spell, they are also very common in production systems. Well, if Java Flight Recorder will be used anything like the JRockit equivalent, at least they will be. Continuous recordings have no end time and will keep recording until the JVM shuts down, or someone tells it to end. This kind of recording can be dumped at any point in time when access to the data being recorded is needed.<\/p>\n<h2>Time Fixed Recordings<\/h2>\n<p>Also known as profiling recordings, these recordings run for a fixed amount of time and then automatically end themselves. These typically use templates that enable costlier events, since the performance penalty will only be suffered for a limited duration of time.<\/p>\n<p>Note that it is perfectly feasible to have several recordings running in parallel. It is even quite common. Which brings me to the first quirkiness of the Java Flight Recorder: <strong>Recordings active at the same time share the same buffers!<\/strong><\/p>\n<p>It may be easier to consider recordings to be named sets of Event Type settings, i.e. settings of what to record, that are being pushed and popped from the recording engine. At any given time, the union of the settings dictates what will be recorded.<\/p>\n<p>Here is an example:<br \/>\nA continuous recording R<sub>0<\/sub> is started at T<sub>0<\/sub> with settings S<sub>0<\/sub>. After a while, a time fixed recording R<sub>1<\/sub> is started at T<sub>1<\/sub> with settings S<sub>1<\/sub>, where S<sub>1<\/sub> \u2283 S<sub>0<\/sub>. The time fixed recording R<sub>1<\/sub> ends at T<sub>2<\/sub>. This is what will be recorded:<\/p>\n<table width=\"500\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<th style=\"background-color: #b62011\" valign=\"top\" width=\"250\">Time<\/th>\n<th style=\"background-color: #b62011\" valign=\"top\" width=\"250\">Settings<\/th>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"250\">T<sub>0<\/sub>\u2192T<sub>1<\/sub><\/td>\n<td valign=\"top\" width=\"250\">S<sub>0<\/sub><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"250\">T<sub>1<\/sub>\u2192T<sub>2<\/sub><\/td>\n<td valign=\"top\" width=\"250\">S<sub>0<\/sub> \u222a S<sub>1<\/sub><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"250\">&gt;T<sub>2<\/sub><\/td>\n<td valign=\"top\" width=\"250\">S<sub>0<\/sub><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that this means that if you dump the continuous recording R<sub>0<\/sub> for a time range intersecting [T<sub>1<\/sub>,T<sub>2<\/sub>], you will actually find that you are getting information in your \u201crecording\u201d that you did not ask for in the settings (S<sub>0<\/sub>). All this in the name of performance. <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-winkingsmile\" style=\"border-style: none\" alt=\"Blinkar\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2013\/09\/wlEmoticon-winkingsmile1.png\" \/> Once T<sub>2<\/sub> arrives, the settings for R<sub>1<\/sub> will be popped, and we\u2019re back to just recording S<sub>0<\/sub>.<\/p>\n<p>Now, one last reminder before getting back to the actual recording:<\/p>\n<table width=\"500\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<th style=\"background-color: #b62011\" valign=\"top\">The 1<sup>st<\/sup> Rule of Flight Recording*<\/th>\n<\/tr>\n<tr>\n<td valign=\"top\"><span style=\"font-size: small\">Thou Shalt Never Forget to Start Your JVM with<br \/>\n<\/span><span style=\"background-color: #ffff00;color: #000000;font-family: Courier New;font-size: medium\">-XX:+UnlockCommercialFeatures -XX:+FlightRecorder<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>RAmen!<br \/>\n(* Only required in HotSpot. With JRockit, no command line flags are required.)<\/p>\n<h2>Creating a Recording from Within Mission Control<\/h2>\n<p>This is probably the easiest way to produce a recording, since you get help both with connecting to the JVM from which you want the recording, and a nice wizard that helps you to select what to record. I went through the recording wizard in the <a href=\"https:\/\/hirt.se\/blog\/?p=364\">blog entry about the method profiler<\/a>, so I will not repeat that here. I will just note that the template settings that you arrive at can be exported from Mission Control, and then stored server side so that anyone connecting to that JVM though Mission Control will have access to it. Simply create a recording with the settings you would like to store, next go to the Template Manager, select the template marked as \u201c \u2013 last saved\u201d and hit Export. Then put the exported file in the <span style=\"font-family: Courier New\">jre\/lib\/jfr <\/span>folder of the JVM where you want to make the template available.<\/p>\n<h2>Creating a Recording Using Command Line Arguments<\/h2>\n<p>This is quite useful when you want to record the start up behaviour of an application, or when you want to make sure that your application always starts with a continuous recording running. Since I am a staunch believer of examples, I\u2019ll simply give three examples.<\/p>\n<p>Here is an example of how to start a one minute time fixed recording, 20 seconds after the JVM has started, using the profile template :<br \/>\n<code>-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=delay=20s,duration=60s,name=MyRecording,filename=C:\\demo\\myrecording.jfr,settings=profile<\/code><\/p>\n<p>Note that the settings parameter either takes a path to a template, or the name of a template which must be available in the <span style=\"font-family: Courier New\">jre\/lib\/jfr<\/span> folder of the JVM.<\/p>\n<p>Here is an example on how to start a continuous recording, using the default template:<br \/>\n<code>-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=name=MyRecording,settings=default<\/code><\/p>\n<p>Note that in the second example we do not specify any file name. The data will need to be dumped on request, either using Mission Control or jcmd, or possibly by using the dump-on-exit parameters to make the JVM dump the recording when exiting the JVM, like this:<br \/>\n<code>-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=c:\\demo\\dumponexit.jfr <\/code><\/p>\n<p>For more information on the available parameters, see the <a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/technotes\/tools\/windows\/java.html\">Java Command Line Reference<\/a>.<\/p>\n<h2>Creating a Recording Using JCMD<\/h2>\n<p>You can also control the Flight Recorder even after you have started the java process (as long as you adhere to the 1st Rule of Flight Recording) using JCMD. The JCMD utility is in the JAVA_HOME\/bin folder and allows you to enumerate the locally running Java processes, and send commands to them. Just running jcmd will list the running Java processes and their PIDs:<\/p>\n<p><code>C:\\Java\\jmc5.2labs&gt;jcmd<br \/>\n4711 LoadAndDeadlock<br \/>\n1276 sun.tools.jcmd.JCmd <\/code><\/p>\n<p>To query a certain JVM for the available commands, use \u201chelp\u201d:<\/p>\n<p><code><br \/>\nC:\\Java\\jmc5.2labs&gt;jcmd 7484 help<br \/>\n7484:<br \/>\nThe following commands are available:<br \/>\nJFR.stop<br \/>\nJFR.start<br \/>\nJFR.dump<br \/>\nJFR.check<br \/>\nVM.native_memory<br \/>\nVM.commercial_features<br \/>\nManagementAgent.stop<br \/>\nManagementAgent.start_local<br \/>\nManagementAgent.start<br \/>\nThread.print<br \/>\nGC.class_histogram<br \/>\nGC.heap_dump<br \/>\nGC.run_finalization<br \/>\nGC.run<br \/>\nVM.uptime<br \/>\nVM.flags<br \/>\nVM.system_properties<br \/>\nVM.command_line<br \/>\nVM.version<br \/>\nhelp<br \/>\nFor more information about a specific command use 'help &lt;command&gt;'. <\/code><\/p>\n<p>Here is an example which starts a continuous recording from the command line using JCMD (assuming that the PID of the Java process you want to record on is 4711):<\/p>\n<p><code>C:\\Java\\jmc5.2labs&gt;jcmd 7484 JFR.start name=MyRecording settings=default<br \/>\n4711: Started recording 1. No limit (duration\/maxsize\/maxage) in use. <\/code><\/p>\n<p>Use JFR.dump name=MyRecording filename=FILEPATH to copy recording data to file.<\/p>\n<p>The JFR.check command can be used to check the status of the recordings:<\/p>\n<p><code>C:\\Java\\jmc5.2labs&gt;jcmd 4711 JFR.check<br \/>\n4711:<br \/>\nRecording: recording=1 name=\"MyRecording\" (running) <\/code><\/p>\n<p>To dump the recording:<\/p>\n<p><code>C:\\Java\\jmc5.2labs&gt;jcmd 4711 JFR.dump name=MyRecording filename=C:\\demo\\jcmddump .jfr<br \/>\n4711:<br \/>\nDumped recording \"MyRecording\", 180.3 MB written to: <\/code><\/p>\n<p>C:\\demo\\jcmddump.jfr<\/p>\n<p>Then you can just drag and drop the resulting file into Mission Control to view the contents:<\/p>\n<p><span style=\"font-size: medium\">\u00a0<a href=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2013\/09\/pretty.png\"><img loading=\"lazy\" decoding=\"async\" style=\"padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px\" title=\"pretty\" alt=\"pretty\" src=\"https:\/\/hirt.se\/blog\/wp-content\/uploads\/2013\/09\/pretty_thumb.png\" width=\"636\" height=\"484\" border=\"0\" \/><\/a><br \/>\n<\/span><span style=\"font-size: small\"><em>(No blog post is complete without a Pretty Picture\u2122.)<\/em><\/span><\/p>\n<p><strong><span style=\"font-size: large\">Further reading and useful links<\/span><\/strong><\/p>\n<p>Related Blogs:<br \/>\n<a href=\"https:\/\/hirt.se\/blog\/?p=343\">Java Mission Control Finally Released<\/a><br \/>\n<a href=\"https:\/\/hirt.se\/blog\/?p=347\">My JavaOne 2013 Sessions<\/a><br \/>\n<a href=\"https:\/\/hirt.se\/blog\/?p=364\">Low Overhead Method Profiling with Mission Control<\/a><\/p>\n<p>The Mission Control home page:<br \/>\n<a href=\"http:\/\/oracle.com\/missioncontrol\">http:\/\/oracle.com\/missioncontrol<\/a><\/p>\n<p>Mission Control Base update site for Eclipse:<br \/>\n<a title=\"https:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/5.2.0\/eclipse\/\" href=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/base\/5.2.0\/eclipse\/\">http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/base\/5.2.0\/eclipse\/<\/a><\/p>\n<p>Mission Control Experimental update site (Mission Control plug-ins):<br \/>\n<a title=\"https:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/5.2.0\/eclipse\/\" href=\"http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/5.2.0\/eclipse\/\">http:\/\/download.oracle.com\/technology\/products\/missioncontrol\/updatesites\/experimental\/5.2.0\/eclipse\/<\/a><\/p>\n<p>The Mission Control Facebook Community Page (not kidding):<br \/>\n<a title=\"http:\/\/www.facebook.com\/pages\/Java-Mission-Control\/275169442493206\" href=\"http:\/\/www.facebook.com\/pages\/Java-Mission-Control\/275169442493206\">http:\/\/www.facebook.com\/pages\/Java-Mission-Control\/275169442493206<\/a><\/p>\n<p>Mission Control on Twitter:<br \/>\n<a href=\"http:\/\/twitter.com\/javamissionctrl\">@javamissionctrl<\/a><\/p>\n<p>Me on Twitter:<br \/>\n<a href=\"http:\/\/twitter.com\/hirt\">@hirt<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the Hotspot JDK 7u40 there is a nifty new tool called Java Mission Control. Users of the nifty old tool JRockit Mission Control will recognize a lot of the features. This particular blog entry focuses on the Java Flight Recorder and various ways you can go about to create a flight recording. In the [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-370","post","type-post","status-publish","format-standard","hentry","category-java-mission-control-fair-dj"],"_links":{"self":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/370","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=370"}],"version-history":[{"count":4,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/370\/revisions"}],"predecessor-version":[{"id":397,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=\/wp\/v2\/posts\/370\/revisions\/397"}],"wp:attachment":[{"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=370"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=370"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hirt.se\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=370"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}