Until now, we have only looked at live sessions where the JProfiler GUI obtains the data from the profiling agent that is running inside the profiled JVM. JProfiler also supports snapshots where all profiling data is written to a file. This can be of advantage in several scenarios:
- You record profiling data automatically, for example as part of a test so that connecting with a JProfiler GUI is not possible.
- You want to compare profiling data from different profiling sessions or look at older recordings.
- You want to share profiling data with somebody else.
Snapshots include data from all recordings, including heap snapshots. To save disk space, snapshots are compressed, except for heap walker data which has to remain uncompressed to allow for direct memory mapping.
Saving and opening snapshots in the JProfiler GUI
When you are profiling a live session, you can create snapshots with the Save Snapshot tool bar button. JProfiler pulls all profiling data from the remote agent and saves it to a local file with a ".jps" extension. You can save multiple such snapshots during the course of a live session. They are not opened automatically and you can continue to profile.
Saved snapshots are added automatically to the File->Recent Snapshots menu, so you can conveniently open a snapshot that you have just saved. When opening a snapshot while the live session is still running, you have a choice of terminating the live session or opening another JProfiler window.
When you use the snapshot comparison feature in JProfiler, the list of snapshots is populated with all the the snapshots that you have saved for the current live session. This makes it easy to compare different use cases.
In general, you can open snapshots by invoking Session->Open Snapshot from the main menu or by double-clicking the snapshot file in the file manager. JProfiler's IDE integrations also support opening JProfiler snapshots through the generic Open File actions in the IDEs themselves. In that case, you get source code navigation into the IDE instead of the built-in source code viewer.
When you open a snapshot, all the recording actions are disabled and only views with recorded data are available. To discover what kind of data has been recorded, hover the mouse over the recording label in the status bar.
Profiling short-lived programs
For a live session, all profiling data resides in the process of the profiled JVM. So when the profiled JVM is terminated, the profiling session in JProfiler is closed as well. To continue profiling when a JVM exits, you have two options, both of which can be activated in the session startup dialog.
- You can prevent the JVM from actually exiting and keep it artificially alive as long as the JProfiler GUI is connected. This may be undesirable when you are profiling a test case from the IDE and want to see the status and total time in the test console of the IDE.
- You can ask JProfiler to save a snapshot when the JVM terminates and switch to it immediately. The snapshot is temporary and will be discarded when you close the session unless you use the Save Snapshot action first.
Saving snapshots with triggers
The final result of an automated profiling session is always a snapshot or a series of snapshots. In triggers, you can add a "Save a snapshot" action that saves the snapshot on the machine where the profiled JVM is running. When the trigger runs during a live session, the snapshot is also saved on the remote machine and may not include parts of the data that have already been transmitted to the JProfiler GUI.
There are two basic strategies for saving snapshots with triggers:
- For test cases, start recording in the "JVM startup" trigger and add a "JVM exit" trigger to save the snapshot when the JVM is terminated.
- For exceptional conditions like the "CPU load threshold" trigger or for periodic profiling with a "Timer trigger", save the snapshot after recording some data with a "Sleep" action in between.
HPROF heap snapshots
In situations where taking a heap snapshot produces too much overhead or consumes too much memory, you can use the HPROF heap snapshots that the JVM offers as a built-in feature. Because the profiling agent is not required for this operation, this is interesting for analyzing memory problems in JVMs that are running in production.
With JProfiler, there are three ways to obtain such snapshots:
For live sessions, the JProfiler GUI offers an action in the main menu to trigger an HPROF heap dump.
JProfiler has a special "Out of memory exception" trigger to save an HPROF snapshot when an
OutOfMemoryErroris thrown. This corresponds to the VM parameterthat is supported by HotSpot JVMs.
The jmap executable in the JDK can be used to extract an HPROF heap dump from a running JVM.
JProfiler includes the command line tool
jpdumpthat is more versatile than jmap. It lets you select a process, can connect to processes running as a service on Windows, has no problems with mixed 32-bit/64-bit JVMs and auto-numbers HPROF snapshot files. Execute it with the
-helpoption for more information.
JDK Flight Recorder snapshots
The JDK includes the JDK Flight Recorder (JFR) mechanism to capture events regarding method execution, object allocations, and other important subsystems of the JVM and save them to snapshots. Production environments may opt for a continuous use of this technology to minimize overhead and provide data for troubleshooting. JFR snapshots can be recorded and saved with the jcmd executable in the JDK using the commands that start with "JFR.".
With JProfiler, you can open JDK Flight Recorder snapshots to analyze the recorded data. When opening JFR snapshots, only a fraction of JProfiler's views will be shown in the view selector corresponding to the types of data that are available from JFR recording.
First, the telemetry section is populated with a subset of JProfiler's telemetries, other telemetries are shown in the corresponding probe views. The "Memory" telemetry is only populated if heap statistics are recorded. There are some differences to the default JProfiler telemetries, for example, "Recorded throughput" shows sizes and not object counts.
Call tree and hot spot views are available, with the limitation that the "Runnable" thread state does not measure times in JFR, but shows sample counts. The other thread states like "Waiting" or "Blocking" still measure times. Because of this discrepancy, the "All thread states" mode is not available in the thread status selector. Also, the non-Runnable thread states are calculated from events which have a configurable minimum duration threshold that is shown in the thread status selector. The actual total time of these thread states may be significantly larger.
Because JFR works with fixed buffers, long call stacks are truncated. Truncated traces are not suitable for building an understandable call tree, so these traces are shown below a specially marked node. With the
VM parameter, you can increase the size of the corresponding buffer in JFR and get rid of truncated traces for your application.
For memory recording, the recorded objects, allocation call tree and allocation hot spots views show the JFR allocation profiling data. The most important difference is that the recording uses allocation sampling, but the reported sizes are estimated total sizes. Only recorded objects are shown, statistics for all objects are not available. If heap statistics are recorded, the "Live objects" view will show class statistics for objects that are still on the heap after a full garbage collection. The "Difference" column shows how the numbers have changed between the first and the last heap statistics. If these times do not coincide with the start and end points of the snapshot recording, corresponding bookmarks are added in the telemetry views. Only classes with a total object size above a fixed threshold (usually 1% of the heap) are recorded. By default, this feature is disabled in JFR because it introduces a substantial overhead.
In the "Monitors & locks" section, only the monitor history and the monitor usage statistics views are present. In particular, the locking history graph is unavailable, so that the monitor tool tips in the thread history view link to the monitor usage history view.
Probes are shown for classes, sockets, files and exceptions. Data in these probes is only shown if the corresponding data recording has been configured for JFR. There is no thread status selector in the probe call tree and hot spots views and the probe tracker is unavailable.
When opening very large JFR snapshots, you can speed up snapshot processing and reduce memory usage by clicking on the "Customize analysis" check box in the file chooser and excluding the event types that are not required for your analysis. For example, if you are only interested in CPU data, you can exclude monitor events.