Snapshots


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:

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.

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:

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:

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

-XX:FlightRecorderOptions=stackdepth=>nnnn<

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.