Friday, April 11, 2014

Looking for a Java Profiler. No IntelliJ IDEA profiler? What to do?

I have previously written about NetBeans 8 vs. IntelliJ IDEA 13. One thing I am missing in IntelliJ is a profiler. The advantages in having a profiler integrated into the IDE compared to having the profiler running on the side are multiple: the profiler is integrated into the IDE's start application functionality and so is the ability to go directly to the (slow) profiled code to name a few.

However, IDEA does not ship with a profiler. I know that it integrates very nicely with JProfiler but that is a rather expensive tool. This led me to look for other options. I have previously used VisualVM but Mission Control caught my eye as it has a cool feature called Flight Recorder (a low overhead profiler that you can use in production). It requires you have a recent JVM that bundles Mission Control (a recent Java 7 or 8 will do) + for running your app with the extra options that I'll show below.

Run options

From within IDEA: 

To address the first problem, profiling a unit test or app from with IDEA, here is what I do. When you start you app or unit test from with in IDEA add this to the run configuration's VM options:

-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=120m,filename=recording.jfr

It starts the flight recorder immediately and runs it for up to 120 minutes. It puts the results in a file called recording.jfr in the root project folder. When done or after 120 minutes you can then open the file using Mission Control and view for instance the Code tab's Hot Methods tab.

Of course you can also just connect Mission Control to the running process that is execution you code directly. You do this by having Mission Control open and select the the Flight Recorder item in the JVM Browser of the process. But it is nice to know that you can make it start along side the actual application start using the above configuration.

Options intermezzo:

When you want to do more experimentation you can add an extra settings argument to the XX:StartFlightRecording (see Maven example below). The argument must equal a file name in the JRE_HOME/lib/jfr folder. The files contain information on for instance sampling rate, what will be recorded (for instance what JVM and OS metrics) etc. You can edit it in Mission Control in the Flight Recording Template Manager.

From the console using Maven:

If you prefer the console, here are some nifty Maven commands:

To run tests that match Profile* and profile them (note that if you use Surefire and already have an argLine in the pom.xml file, then you can't override it from the console):

mvn -Dtest=Profile* test -DargLine="-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=filename=result.jfr,duration=120m,settings=MyWicketSettings.jfc"

Run app with profiling enabled (here a Spring boot app):

MAVEN_OPTS="-XX:+UnlockCommercialFeatures -XX:+FlightRecorder" mvn spring-boot:run

With that command you have enabled Flight Recorder. You can then open Mission Control when you want to look at the apps performance etc.