What's new in JProfiler 16.0

Change release:

Please see the change log for a detailed list of changes.

JProfiler 16.0 introduces the following notable new features:

JProfiler 16 introduces an AI probe. The probe measures interactions with LLMs via LangChain4j and Spring AI.

Chat requests and embeddings are supported and shown in the events view as different event types.

Details for the processed instructions are available in the node detail dialog that can be shown with the hover button in the instructions column. The instructions column shows statistics for the different instruction types, such as user messages, assistant messages, or tool messages.

ScreenshotScreenshot

The AI probe is event-centric. You can work with subsets of recorded events in two ways: First, when you select multiple events, the selection panel at the bottom provides CPU hot spots, probe hot spots, and a probe call tree for the current selection.

ScreenshotScreenshot

For more thorough investigations, the filter selector at the top and the various tabs in the lower section allow you to restrict the set of events in the main table and associated views.

ScreenshotScreenshot

By default, the AI probe identifies hot spots based on the specific model names that processed the request. This data is available not only in the events view, but also in the hot spot view of the AI probe, even if no events are recorded.

ScreenshotScreenshot

Model name hot spots are only one of many potentially interesting types of hot spots. In the probe settings, you can configure a script to calculate user-defined types of hot spots by entering some Java code in JProfiler's powerful script editor.

ScreenshotScreenshot

When an AI probe event is recorded, JProfiler invokes this script with a ModelRequest parameter. This parameter provides access to the request type, the model name, and all instructions along with their instruction types.

For example, you could define hot spots by grouping prompt lengths into 50-character buckets. The example below demonstrates how this is done.

ScreenshotScreenshot

Since JProfiler displays data live during recording, you can change these settings while profiling and observe the effects immediately.

With the above script, the new hot spots look like this:

ScreenshotScreenshot

By default, hot spots focus on the request duration, but you can switch the primary measurement to input tokens and output tokens as well.

This is possible both in the probe hot spots view and the probe call tree view. The probe call tree view shows a top-down view connecting method calls to probe payloads.

ScreenshotScreenshot

The probe telemetries for the AI probe show request counts, average request duration, and a combined input/output token graph separately for chat requests and embedding requests.

ScreenshotScreenshot

Each telemetry can be shown separately and can be used to select events for particular areas of interest.

ScreenshotScreenshot

To help you explore the AI probe, JProfiler now comes with an "LLM demo" session.

It uses Jlama, a cross-platform inference engine for Java 21+ and downloads a 0.5-billion-parameter model from Hugging Face to categorize LLM-related preprints from arXiv.

The demo features a UI where keywords produced by the LLM are continually inserted and you can explore the associated research papers on the right.

ScreenshotScreenshot

JProfiler has a new UI with a modern visual appearance and new icons. We hope you like it! We have light and dark themes. You can see screenshots of them by toggling the dark mode switch at the top of this page.

ScreenshotScreenshot

In addition, the UI is now fully scalable. In the general settings, you can either set a scale factor as a percentage, or set a custom UI font with an arbitrary size, and the UI will be scaled accordingly.

ScreenshotScreenshot

This capability now allows the JProfiler UI to run on Linux with all OpenJDK variants and for all HiDPI resolutions. Previously, only the JetBrains runtime was supported on Linux with HiDPI resolutions.

The JProfiler installer has been modernized, and its default execution mode has been streamlined. By default, no admin privileges are requested unless you choose to install for all users in its customized execution mode.

ScreenshotScreenshot

As a related enhancement, it is now possible to attach to Windows processes running as other users, even if JProfiler is not installed in a directory that is readable by those processes. This is especially important for attaching to Windows services.

ScreenshotScreenshot

JProfiler's probe event recording has been reimplemented. This brings scalability to many millions of events and many new features.

When probes were introduced in JProfiler 7, the focus was on cumulative data, like hot spots and telemetries. Single events were available as a tool for debugging problems, but they were all held in memory, so they were limited to relatively low event counts.

However, keeping all events enables advanced filtering that is impossible to achieve using aggregate data alone. The new file-based backend supports high-throughput recording, enabling complex queries across massive event sets that were previously impossible to process.

The new timeline tab at the bottom of the events view shows a histogram of all recorded events and allows you to select a time range for filtering.

ScreenshotScreenshot

While the table only shows a limited number of events, you can add more events when scrolling to the bottom. When sorting by a column, the entire set of filtered events is considered, not just the currently visible rows.

Totals in the table are also calculated for the entire set of filtered events.

ScreenshotScreenshot

The lower "Hot Spots" tab contains a CPU hot spots view, a probe hot spots view, and a probe call tree – similar to the "Selection" tab, but calculated for all filtered events rather than the selected rows.

In each of these views, you can use the filter button to restrict the displayed events for the main event table and all other views at the bottom. Below you can see a call stack filter in the probe call tree where the filtered node is marked with a filter icon.

ScreenshotScreenshot

Depending on the measurements performed by a probe, additional histogram views are available at the bottom. For the "Files" and the "Sockets" probes these are "Duration" and "Throughput".

Histograms can be shown with a logarithmic y-axis and support filtering by dragging a range with the mouse.

ScreenshotScreenshot

Finally, smart column management in the events view has been implemented. Based on the width of all columns and the available viewport width, JProfiler decides whether to fit the columns into the viewport or activate horizontal scrolling. Resizing columns manually disables the "fit-to-viewport" mode, which automatically reactivates if the total table width becomes smaller than the viewport.

The probe call tree and probe hot spots views now have a metric selector if a probe has additional measurements beyond event duration. For example, the "Files" and the "Sockets" probes also offer "Read Throughput" and "Write Throughput". Selecting one of the throughput metrics automatically restricts the view to "Read" or "Write" events, respectively.

Changing the metric recalculates hot spots and updates the hot paths in the probe call tree.

ScreenshotScreenshot

Metric selectors are now also available on the "Selection" and "Hot Spots" tabs of the probe events view. Since "Read" and "Write" events can be filtered separately in the events view, there is a single combined "Throughput" measurement.

ScreenshotScreenshot

JProfiler 16 delivers many improvements for JFR support.

  • Responsiveness in the event browser for large event counts has been improved by pre-calculating the data in the lower views.
  • Previous versions of JProfiler only handled a maximum number of events in the event table. You can now load additional events by scrolling to the bottom. Additionally, when sorting the table, all filtered events are considered rather than just the visible subset.
  • The totals in the event table are now calculated for all filtered events, not just for the currently displayed ones.
ScreenshotScreenshot

Support for throttle settings has been added in the JFR recording wizard. For example, the new jdk.CPUTimeSample event in Java 25 is configured via throttling. You can alternatively enter a period or an emission rate with a /s unit.

ScreenshotScreenshot

Throttle settings are also displayed in the CPU views next to the thread status selector.

ScreenshotScreenshot

For calculating data in the CPU section, the new Linux-only jdk.CPUTimeSample event (Java 25+) is now used if recorded, instead of the older jdk.ExecutionSample event. Unlike jdk.ExecutionSample, which works on all platforms, but has limitations in the number of threads it samples and the accuracy of CPU usage, jdk.CPUTimeSample uses CPU time events from the Linux kernel to collect data.

With this event, CPU profiling with JFR can now provide actionable CPU metrics on production systems where loading a JVMTI agent is not permitted.

ScreenshotScreenshot

Starting with JProfiler 16, all experimental JFR events are now shown in the event browser, such as the jdk.CPUTimeSample event.

ScreenshotScreenshot

JProfiler 16 introduces support for virtual thread dumps.

The thread dumps view now features two distinct actions: one for platform thread dumps and another for virtual thread dumps.

While the virtual thread dump also includes platform threads, it is asynchronous, so synchronous platform thread dumps are preferable when not working with virtual threads.

ScreenshotScreenshot

Virtual threads are hierarchically organized within their thread containers. This is relevant when using structured concurrency, which is still a preview feature as of Java 25.

In structured concurrency, each scope creates a corresponding thread container. Since a dump may contain millions of virtual threads in deeply nested containers, virtual thread dumps can be significantly larger than platform thread dumps.

ScreenshotScreenshot

You can compare two single virtual threads or two entire thread dumps by selecting them and choosing the comparison action in the context menu.

ScreenshotScreenshot

The comparison is shown in a diff viewer in a separate window.

ScreenshotScreenshot

To copy single threads, multiple threads, or entire thread dumps to the clipboard, use the corresponding action in the context menu.

ScreenshotScreenshot

Virtual thread dumps group threads with the same stack trace in the same hierarchical position into a single node.

The context menu contains an action to show all grouped thread names.

ScreenshotScreenshot

The names of grouped threads are displayed in a separate window where you can filter for thread names of interest.

ScreenshotScreenshot

Thread grouping is also supported for platform thread dumps.

You can now analyze the contribution of single threads in a cumulative call tree. In the call tree view, select "Show Threads" from the context menu to calculate this data for the selected node.

ScreenshotScreenshot

A separate dialog with a percentage breakdown of all contributing threads is shown. You can optionally select one thread and switch to the call tree for that thread in the call tree view.

The feature helps identify thread-specific performance issues. For example, you may want to isolate a misbehaving thread from a thread pool.

ScreenshotScreenshot

The node detail dialog was improved in several ways.

The node detail dialog is an important tool to display more information for selected elements and is available from the "View" menu or the context menu.

When selecting multiple nodes in hot spots views, cumulative statistics for the selection are now displayed.

ScreenshotScreenshot

Many tables in JProfiler have columns containing long text that exceeds the column width. The node detail dialog shows the complete text in this case. Starting with JProfiler 16, there is a hover button that directly opens the node detail dialog and activates the correct tab if there are multiple long text columns in the table.

ScreenshotScreenshot

In the heap walker, the node detail dialog now shows the full values for string values in the reference views, not just the displayed truncated preview string.

ScreenshotScreenshot

JProfiler now supports deobfuscation for snapshot comparisons.

Previously, when comparing snapshots from an obfuscated application, there was no way to deobfuscate classes and methods. Below, you can see an example of a comparison using obfuscated names.

ScreenshotScreenshot

Similar to the existing deobfuscation support when opening snapshots, the file chooser now includes a "Deobfuscate" check box when adding snapshots to the comparison window.

ScreenshotScreenshot

When selected, a dialog with a drop-down for supported obfuscators and a field for the mapping file path appears.

If different snapshot files have different mapping files, you can add the snapshots individually.

ScreenshotScreenshot

Once the mapping file is applied, all comparisons in JProfiler now show the original class and method names.

ScreenshotScreenshot

Timeline views now support row pinning.

In the threads history view and in all the probe timeline views, you can pin selected rows via the context menu. These are shown in a separate area at the top where you can use drag and drop to change their order.

ScreenshotScreenshot

You can unpin pinned rows individually or all at once.

ScreenshotScreenshot

JProfiler 16 also introduces a sorting drop-down that offers ascending and descending sort directions and a new default sort mode where active long-lived rows are shown first, followed by recently closed rows.

ScreenshotScreenshot

JProfiler 16 adds full support for profiling Java 26.

This version is essential if you are profiling virtual threads or if you are using the new built-in HTTP/3 support in the JDK HTTP client.