Sometimes writing code that just runs is not enough. We might want to know what goes on internally such as how memory is allocated, consequences of using one coding approach over another, implications of concurrent executions, areas to improve performance, etc. We can use profilers for this.
A Java Profiler is a tool that monitors Java bytecode constructs and operations at the JVM level. These code constructs and operations include object creation, iterative executions (including recursive calls), method executions, thread executions, and garbage collections.
JProfiler is a top choice for many developers. With an intuitive UI, JProfiler provides interfaces for viewing system performance, memory usage, potential memory leaks, and thread profiling.
With this information, we can easily know what we need to optimize, eliminate, or change – in the underlying system.
Here’s what the JProfiler’s interface looks like:
Like most profilers, we can use this tool for both local and remote applications. This means that it’s possible to profile Java applications running on remote machines without having to install anything on them.
JProfiler also provides advanced profiling for both SQL and NoSQL databases. It provides specific support for profiling JDBC, JPA/Hibernate, MongoDB, Casandra, and HBase databases.
The below screenshot shows the JDBC probing interface with a list of current connections:
If we are keen on learning about the call tree of interactions with our database and see connections that may be leaked, JProfiler nicely handles this.
Live Memory is one feature of JProfiler that allows us to see current memory usage by our application. We can view memory usage for object declarations and instances or for the full call tree.
In the case of the allocation call tree, we can choose to view the call tree of live objects, garbage-collected objects, or both. We can also decide if this allocation tree should be for a particular class or package or all classes.
The screen below shows the live memory usage by all objects with instance counts:
JProfiler supports integration with popular IDEs such as Eclipse, NetBeans, and IntelliJ. It’s even possible to navigate from snapshot to source code!
YourKit Java Profiler runs on many different platforms and provides separate installations for each supported operating system (Windows, MacOS, Linux, Solaris, FreeBSD, etc.).
Like JProfiler, YourKit has core features for visualizing threads, garbage collections, memory usage, and memory leaks, with support for local and remote profiling via ssh tunneling.
Here’s a quick look at the memory profiling results of a Tomcat server application:
YourKit also comes in handy those times when we want to profile thrown exceptions. We can easily find out what types of exceptions were thrown and the number of times each exception occurred.
YourKit has an interesting CPU profiling feature that allows focused profiling on certain areas of our code such as methods or subtrees in threads. This is very powerful as it allows for conditional profiling through its what-if feature.
Figure 5 shows an example of the thread-profiling interface:
We can also profile SQL, and NoSQL database calls with YourKit. It even provides a view for actual queries that were executed.
Though this is not a technical consideration, the permissive licensing model of YourKit makes it a good choice for multi-user or distributed teams, as well as for single-license purchases.
4. Java VisualVM
Java VisualVM is a simplified yet robust profiling tool for Java applications. By default, this tool is bundled with the Java Development Kit (JDK). Its operation relies on other standalone tools provided in the JDK, such as JConsole, jstat, jstack, jinfo, and jmap.
Below, we can see a simple overview interface of an ongoing profiling session using Java VisualVM:
One interesting advantage of Java VisualVM is that we can extend it to develop new functionalities as plugins. We can then add these plugins to Java VisualVM’s built-in update center.
Java VisualVM supports local and remote profiling, as well as memory and CPU profiling. Connecting to remote applications requires providing credentials (hostname/IP and password as necessary) but does not provide support for ssh tunneling. We can also choose to either enable real-time profiling with instant updates (typically every 2 seconds).
Below, we can see the memory outlook of a Java application profiled using Java VisualVM:
With the snapshot feature of Java VisualVM, we can take snapshots of profiling sessions for later analysis.
5. NetBeans Profiler
The NetBeans Profiler is bundled with Oracle’s open source NetBeans IDE.
While this profiler shares a lot of similarities with Java VisualVM, it’s a good choice when we want everything wrapped in one program (IDE + Profiler).
All other profilers discussed above provide plugins to enhance IDEs integration.
Below screenshot shows an example of the NetBeans Profiler interface:
Netbeans Profiler is also a good choice for lightweight development and profiling. NetBeans Profiler provides a single window for configuring and controlling the profiling session and displaying the results. It gives a unique feature of knowing how often garbage collection occurs.
6. Other Solid Profilers
Some honorable mentions here are Java Mission Control, New Relic, and Prefix (from Stackify) – these have less market share overall, but definitely, do deserve a mention. For example, Stackify’s Prefix is an excellent lightweight profiling tool, well-suited for profiling not only Java applications but other web applications as well.
In this write-up, we discussed profiling and Java Profilers. We looked at the features of each Profiler and what informs the potential choice of one over another.
There’re many Java profilers available with some having unique characteristics. The choice of which Java profiler to use, as we’ve seen in this article, is mostly dependent on a developer’s selection of tools, the level of analysis required, and features of the profiler.