JProfiler MCP Server: Tool and Resource Reference
This reference is generated from the running MCP server and lists all tools and resources exactly as an AI agent sees them after connecting. Go back to MCP server setup.
For agent consumption, this page is also available as raw Markdown.
JProfiler is a Java profiler whose MCP (Model Context Protocol) server gives AI coding agents direct access to its profiling and analysis capabilities: recording CPU, allocation and probe data from running JVMs, analyzing heap dumps and snapshots, and drilling into the recorded data with a jq-based query interface.
This document is generated from the running server and lists all tools and resources exactly as an agent sees them after connecting. It is intended both for developers who want to understand what the integration can do and for AI agents that evaluate whether to install it.
The quickest way to connect an agent is the npm wrapper, which downloads and provisions JProfiler automatically and offers to start a free evaluation license on first use:
{
"mcpServers": {
"JProfiler": {
"command": "npx",
"args": ["-y", "@ej-technologies/jprofiler-mcp@latest"]
}
}
}
For other installation options, see https://www.ej-technologies.com/jprofiler/mcp.
Generated from JProfiler 16.3.
Contents
Tools: prepare_profiling, load_snapshot, attach, check_status, query, create_heap_dump, attached_action, list_jvms
Resources: jprofiler://datasets, jprofiler://config/session, jprofiler://config/probes, jprofiler://probes/custom, jprofiler://api/method-scripts, jprofiler://api/heap-scripts, jprofiler://api/controller, jprofiler://api/probe-embedded, jprofiler://api/probe-injected
Tools
prepare_profiling
Prepare a profiling session by retrieving a JVM parameter to be added to a Java process call to record performance data with stack traces for the following subsystems: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process. The result is a JSON object containing a 'jvmParameter' to be added (quoted) to the Java process at startup. Add it verbatim and do not create or modify any files; the configuration is already set up for you. If the result contains 'additionalJvmParameters' (discovery of injected custom probes), add each element as a separate VM argument as well. Keep this MCP server running and run the Java process. It waits for the server to connect before application startup. During recording, attached_action can perform live actions. The recording is saved automatically when the JVM terminates, after the optional maximum duration, or when check_status is called with 'stopRecording: true'. Then call check_status to access the data - do not load the saved snapshot file yourself. Saving disconnects from the JVM. Use attach with its PID for another recording if it is still running.
| Parameter | Type | Required | Description |
|---|---|---|---|
delay | integer | no | An optional recording delay in seconds measured from the successful connection to the JVM. |
maximumDuration | integer | no | An optional maximum recording duration in seconds measured from recording startup. If not specified, data will be saved at JVM termination or when check_status is called with 'stopRecording: true'. |
recordingConfig | object | no | What to record in this session. Every key is optional and omitted keys keep their defaults - set only the keys this analysis needs, such as recordMonitors for lock contention analysis, recordAllocations for allocation sites, triggers for automatic captures during the recording, or advanced.methodCallRecordingType instrumentation when invocation counts are needed. |
Properties of recordingConfig
| Parameter | Type | Required | Description |
|---|---|---|---|
recordAllocations | boolean | no | Record allocation data with call stacks instead of performance data. The two are exclusive because recording both distorts the results. Valuable on its own via the allocation datasets, and a heap dump taken in such a session additionally carries per-object allocation sites (heap.allocation* datasets). Allocation data is sampled, not exact. Default false |
recordMonitors | boolean | no | Also record monitor and lock events: threads blocked on monitors, waiting in Object.wait or parked, with stack traces. Composes with performance and allocation recording and enables the monitor.* datasets for contention, lock-order inversion and deadlock analysis. Default false |
blockingThresholdMicros | integer | no | Optional minimum duration in microseconds for blocked monitor events when 'recordMonitors' is true, shorter events are discarded. Default 1000 |
waitingThresholdMicros | integer | no | Optional minimum duration in microseconds for waiting and parked monitor events when 'recordMonitors' is true, shorter events are discarded. Default 100000 |
subsystems | array of string | no | The subsystems to record in this session. Subsystems not listed are not recorded. Built-in values: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, socket, file, process, gc. Custom probes of the profiled application (embedded or injected probe classes) are recorded as 'custom:<fully qualified probe class name>', e.g. custom:com.example.MyProbe. Script probes are not listed here, they are defined in 'advanced.scriptProbes' and recorded as 'script:<name>'. Default: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process, gc. |
advanced | object | no | Settings that are off by default. Only change them for a concrete reason, never speculatively - more data is not better, and a wrong value can silently lose data. Valid reasons are e.g. check_status reporting possibleInlineAsyncTypes, an application that hands work to thread pools, coroutines or event dispatch threads, an analysis that needs invocation counts, or a previous recording showing that the default filters hide relevant code. The keys without a description correspond to session configuration attributes (such as splittingCap for the call tree split cap mentioned in capped_split warnings) and are documented in the resource jprofiler://config/session. |
triggers | array of object | no | Actions executed automatically when an event occurs during the recording. Use them for conditions that interactive tool calls cannot catch: recordings from JVM start, long-running sessions and transient states like heap spikes, or work scoped to a method with 'methodInvocation'. MBean snapshots and heap dumps captured by triggers become part of the session snapshot and are queried like manually captured ones. Example: {"on": "timer", "intervalSeconds": 60, "actions": [{"type": "mbeanSnapshot"}]} |
Properties of recordingConfig.advanced
| Parameter | Type | Required | Description |
|---|---|---|---|
filter | string | no | Comma-separated list of project packages to profile (e.g. 'com.example.app,org.service'). A wrong package silently excludes relevant code from the recording. |
inlineAsyncTypes | array of string | no | Record async request tracking for the given types, one or more of executor, kotlin_coroutines, awt, swt, virtual_thread, platform_thread. Async executions are then inlined under their call sites in the call tree and hotspot datasets. Off by default because tracking adds overhead - enable when analyzing applications that hand work to thread pools, coroutines or event dispatch threads, or when check_status reports possibleInlineAsyncTypes after a previous recording. |
methodCallRecordingType | string | no | How CPU method calls are recorded. 'sampling' (default) takes periodic call stack samples: very low overhead that does not depend on the package filter, accurate times, but no invocation counts, and methods shorter than the sampling period or called rarely can be missed. 'instrumentation' modifies the bytecode of profiled classes to track method entry and exit: the only mode with exact invocation counts (the count field in the performance datasets) and reliable timing of small, frequently called methods, and it makes allocation stack traces exact; the cost is high overhead and distorted CPU times in CPU-bound code, so it requires a package filter (filter in this object) that restricts instrumentation to the relevant packages. 'async_sampling' samples asynchronously without safepoint bias: the most accurate CPU times for highly multithreaded CPU-bound code, but only on macOS and Linux with a HotSpot JVM (otherwise the agent falls back to sampling), no wall clock times (threadStatus all has no effect) and no invocation counts. Use instrumentation when the analysis needs call counts, otherwise keep the default. One of instrumentation, sampling, async_sampling. |
exceptionalMethods | array of string | no | Methods whose slowest invocations are kept as separate, individually expandable nodes in performance.callTree (marked with exceptionalRun) instead of being merged into the average. Use after performance.outliers shows a method whose maxMicros deviates strongly from its avgMicros. Format: com.foo.Bar.method(long, java.lang.String), exactly as printed in the method field of performance.outliers; the argument list is required, use () for no parameters. Requires methodCallRecordingType 'instrumentation'. Not recorded for virtual threads. |
probeConfig | object | no | Probe-specific settings: a map of subsystem name to a map of attribute name to value, applied to the probe configuration of the recording. Examples: {"jdbc": {"preparedStatementParameters": true}} records prepared statement parameters in the jdbc hotspots, {"http_server": {"split": false}} disables URL call tree splitting of the HTTP server probe, {"http_server": {"splitType": "script", "requestResolvers": ["..."]}} splits the call tree by script-computed request names. Custom probes of the profiled application use the key "custom:<fully qualified probe class name>" with the attributes "events" (record individual events for the probe.events dataset) and "injected" (prepare_profiling and attach pass the probe discovery VM parameter), e.g. {"custom:com.example.MyProbe": {"events": true, "injected": true}} - unknown attributes of custom probes are errors. Script probes defined in 'scriptProbes' use the key "script:<name>" with the attribute "events". Attribute names and values are those of the JProfiler session configuration, the reference with all attributes of all probes is the resource jprofiler://config/probes. Unknown attributes are silently ignored, the applied settings are reported as probeSettings in check_status. |
splitMethods | array of object | no | Split the call tree below the given methods by a script-computed key: each distinct returned string gets its own subtree (type method_split in performance.callTree), for example to analyze request handling per message type. Example: [{"method": "com.example.Handler.onMessage(javax.jms.Message)", "script": "return param0.getJMSType();"}]. Works with any methodCallRecordingType. The script runs on every invocation of the method, so do not split extremely hot methods. The number of distinct keys per split location is capped ('splittingCap', see jprofiler://config/session), further keys are merged into a capped_split node. The script API is documented in the jprofiler://api/method-scripts resource. |
complexityMethods | array of object | no | Measure how the invocation time of the given methods scales with an input size computed per invocation by a script: the complexity.methods dataset then holds the recorded (input size, time) points and curve fits, answering questions like 'is this method O(n^2) in the payload size'. This is the second step after performance.hotspots has identified a suspicious method whose inputs vary in size - re-record with this setting pointing at that method. Example: [{"method": "com.example.Service.process(java.util.List)", "script": "return param0.size();"}]. Works with any methodCallRecordingType. Recording starts with the session and stops before the snapshot is saved; bound the measurement window with startRecording/stopRecording actions ("complexity": true) in triggers or attached_action. The script API is documented in the jprofiler://api/method-scripts resource. |
scriptProbes | array of object | no | Define script probes: lightweight probes declared as scripts, compiled by this server and pushed to the profiled JVM - no code, build or deployment in the profiled application, works on attach. Each probe intercepts the given methods, the script computes the payload string per invocation. Defining a script probe records it: it appears as subsystem 'script:<name>' with payload hot spots in performance.hotspots/callTree; individual events are recorded with 'probeConfig': {"script:<name>": {"events": true}}. Example: [{"name": "Order processing", "methods": [{"method": "com.example.Shop.processOrder(int)", "script": "return "order " + param0;"}]}]. Script probes cannot split the call tree, access return values or create control objects, custom event types or telemetries - for those write a custom probe, see jprofiler://probes/custom. The script API is documented in the jprofiler://api/method-scripts resource. |
scriptClassPath | array of string | no | Additional compile classpath for all scripts in this object ('splitMethods', 'complexityMethods' and script properties in 'probeConfig'): absolute paths to JAR files, to directories containing JAR files, or wildcard patterns like /path/to/lib/*.jar. Only needed when a script references classes beyond the JDK and the JProfiler classes, typically application classes. Used for compilation on this machine only - at runtime the classes must be present in the profiled JVM, which is normally the case for application classes. |
splittingCap | integer | no | Session setting, see the config/session reference. |
exceptionalCap | integer | no | Session setting, see the config/session reference. |
exceptionalTimeType | string | no | Session setting, see the config/session reference. One of all, running, waiting, blocking, netio. |
samplingFrequency | integer | no | Session setting, see the config/session reference. |
samplingNoFilters | boolean | no | Session setting, see the config/session reference. |
lineNumbers | boolean | no | Session setting, see the config/session reference. |
instrumentNativeMethods | boolean | no | Session setting, see the config/session reference. |
recordArrayAlloc | boolean | no | Session setting, see the config/session reference. |
allocationSamplingInterval | integer | no | Session setting, see the config/session reference. |
allocTreeRecordingType | string | no | Session setting, see the config/session reference. One of live, liveAndGcNoClassResolution, liveAndGc. |
utilConcurrentHandling | boolean | no | Session setting, see the config/session reference. |
internalExcludes | boolean | no | Session setting, see the config/session reference. |
libraryDebugParameters | string | no | Session setting, see the config/session reference. |
payloadCap | integer | no | Session setting, see the config/session reference. |
descriptorCap | integer | no | Session setting, see the config/session reference. |
hotspotPayloadCap | integer | no | Session setting, see the config/session reference. |
probeFileMBCap | integer | no | Session setting, see the config/session reference. |
retainStackForHotspotConsolidation | boolean | no | Session setting, see the config/session reference. |
annotateCustomPayloads | boolean | no | Session setting, see the config/session reference. |
samplingPayloadCallStacks | boolean | no | Session setting, see the config/session reference. |
exactSamplingMonitorCallStacks | boolean | no | Session setting, see the config/session reference. |
sampleUnmountedVirtualThreads | boolean | no | Session setting, see the config/session reference. |
asyncThreadResolution | boolean | no | Session setting, see the config/session reference. |
asyncNativeSampling | boolean | no | Session setting, see the config/session reference. |
asyncBufferPercentage | integer | no | Session setting, see the config/session reference. |
Properties of recordingConfig.advanced.splitMethods entries
| Parameter | Type | Required | Description |
|---|---|---|---|
method | string | no | The method below which the call tree is split, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter. |
script | string | no | Java code returning the split key string, or null to leave the invocation unsplit. Available parameters: scriptContext (com.jprofiler.api.agent.ScriptContext, stores per-script state with putObject/getObject and putLong/getLong), clazz (the Class of the declaring class), currentObject (the instance the method is invoked on, null for static methods), param0, param1, ... (the declared method parameters in order). Parameters are statically typed when their class is on the compile classpath and Object otherwise - add application JARs with 'scriptClassPath' to get static typing. |
Properties of recordingConfig.advanced.complexityMethods entries
| Parameter | Type | Required | Description |
|---|---|---|---|
method | string | no | The method whose scaling is measured, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter. |
script | string | no | Java code returning the input size of the invocation as a long, for example 'return param0.size();' for a collection parameter. Same environment as 'splitMethods' scripts (scriptContext, clazz, currentObject, param0, param1, ...). |
Properties of recordingConfig.advanced.scriptProbes entries
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | no | The probe name. The probe is recorded as subsystem 'script:<name>'. |
description | string | no | Optional explanation of the probe's purpose. |
annotatePayloads | boolean | no | Optional: annotate the CPU call tree with the payload strings. Default false. |
methods | array of object | no |
Properties of recordingConfig.advanced.scriptProbes.methods entries
| Parameter | Type | Required | Description |
|---|---|---|---|
method | string | no | The intercepted method, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter. |
script | string | no | Java code returning the payload string for the invocation, or null for no payload. Same environment as 'splitMethods' scripts (scriptContext, clazz, currentObject, param0, param1, ...). |
Properties of recordingConfig.triggers entries
| Parameter | Type | Required | Description |
|---|---|---|---|
on | string | yes | When the actions run: 'start' when the recording starts (after the optional delay for prepare_profiling, right after attaching for attach), 'stop' when the recording stops (JVM exit, maximumDuration or check_status with stopRecording for prepare_profiling, check_status with stopRecording for attach), 'timer' periodically, 'heapThreshold' when the used heap stays above 'percent' of the maximum heap, 'cpuThreshold' when the CPU usage stays above 'percent'. Threshold triggers fire at most about once a minute while the condition holds. 'methodInvocation' fires when the method given in 'method' is entered; with 'waitForFinish' in the actions, the actions before it run on method entry and the actions after it on method exit. A subsystem started by a method trigger is not started automatically at recording start, so the trigger defines the recording scope. One of start, stop, timer, heapThreshold, cpuThreshold, methodInvocation. |
intervalSeconds | integer | no | Required for 'on': 'timer': the period in seconds. |
offsetSeconds | integer | no | Optional for 'on': 'timer': delay of the first fire in seconds. Default 0. With a 0 offset the first fire can land before the application has registered its MBeans or reached its working state, a small offset like 1 avoids a mostly empty first capture. |
count | integer | no | Optional for 'on': 'timer': fire at most this many times. Default unlimited. |
percent | integer | no | Required for 'heapThreshold' and 'cpuThreshold': the threshold in percent. Choose a high value such as 80, the actions fire every time the condition holds. |
method | string | no | Required for 'on': 'methodInvocation': the method in the format com.foo.Bar.method(long, java.lang.String) as printed by the performance.outliers dataset; the argument list is required, use () for no parameters. Method triggers instrument only the named method and work with any method call recording type, including the default sampling. Recursive calls fire only once per outermost invocation. |
actions | array of object | yes | The actions to run when the event fires, in order. |
Properties of recordingConfig.triggers.actions entries
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | yes | 'mbeanSnapshot': capture the current JMX MBean attribute values into the session snapshot (mbean.snapshots dataset). 'heapDump': take a heap dump that becomes part of the session snapshot (heap.* datasets) - expensive, use it with rare events like 'stop' or a high 'heapThreshold', not with 'timer' or 'start'. 'threadDump': take a thread dump that becomes part of the session snapshot (threads.dumps dataset) - cheap, suitable for 'timer' and threshold triggers. 'monitorDump': capture the currently held and waited-on monitors with the involved threads and stack traces (monitor.current dataset) - only the latest dump is kept, repeated fires overwrite it, so prefer events like 'stop' or thresholds over 'timer'. 'markHeap': mark all current heap objects as old, so a heap dump taken later distinguishes objects allocated afterwards (generation 'new' in the heap.* datasets). 'startRecording'/'stopRecording': start or stop recording of subsystems, at least one of 'cpu', 'allocations', 'monitors', 'probes', 'complexity' is required. 'waitForFinish': only for 'methodInvocation', splits the actions into on-entry and on-exit. 'sleep': wait, delays the following actions. One of mbeanSnapshot, heapDump, threadDump, monitorDump, markHeap, startRecording, stopRecording, waitForFinish, sleep. |
filter | string | no | Optional for 'mbeanSnapshot': regular expression matched against the domain and each property value of the MBean object names: "java.lang|com.mycompany.*" captures all MBeans in those domains, "Memory" the java.lang:type=Memory MBean. Without a filter all MBeans are captured, the right choice for exploration. |
label | string | no | Optional for 'mbeanSnapshot' and 'threadDump': label shown in the mbean.snapshots resp. threads.dumps dataset. In triggers the default is a name derived from the event. |
fullGc | boolean | no | Optional for 'heapDump': run a full GC before the dump so only live objects are captured. Default true. |
includeVirtualThreads | boolean | no | Optional for 'threadDump': take a virtual thread dump that includes all virtual threads and the thread container hierarchy in addition to the platform threads. Default false (platform threads only). Virtual threads require JDK 21+. |
cpu | boolean | no | Optional for 'startRecording'/'stopRecording': include CPU recording. |
allocations | boolean | no | Optional for 'startRecording'/'stopRecording': include allocation recording. |
monitors | boolean | no | Optional for 'startRecording'/'stopRecording': include monitor recording. |
complexity | boolean | no | Optional for 'startRecording'/'stopRecording': include complexity recording - requires recordingConfig.advanced.complexityMethods in the same session. Use it to bound the measurement window, for example scoped to a method with a methodInvocation trigger, or to exclude a warmup phase. |
probes | array of string | no | Optional for 'startRecording'/'stopRecording': probe names to start or stop, e.g. ["jdbc"], "custom:<fully qualified probe class name>" for custom probes of the profiled application, or "script:<name>" for a script probe defined in recordingConfig.advanced.scriptProbes. |
seconds | integer | no | Required for 'sleep': the wait time in seconds. |
load_snapshot
Load an existing .jps, .hprof, or .jfr file for analysis. You must call check_status to check the loading progress and - after this returns 'data_ready' - retrieve data with the query tool. To compare two performance snapshots, load both in a single call: set filePath to the run to analyze and baselineFilePath to the baseline; the differences are then reported in the hotspots and call trees of that run.
| Parameter | Type | Required | Description |
|---|---|---|---|
filePath | string | yes | The absolute path to the snapshot file |
baselineFilePath | string | no | An optional baseline snapshot for performance comparisons |
attach
Attach to a running JVM by PID or to a JVM inside a Docker container. Records performance data for the following subsystems: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process until check_status is called with 'stopRecording: true', or allocation data when "recordingConfig": {"recordAllocations": true} is passed. Pass "recordingConfig": {"recordMonitors": true} to additionally record monitor and lock events. You can use list_jvms to discover JVMs.
| Parameter | Type | Required | Description |
|---|---|---|---|
pid | integer | no | The PID of a local JVM process, or the container PID (NSpid) of a JVM inside the specified container. If a container is specified and this is omitted, the topmost JVM in the container is used. |
containerNameOrId | string | no | The name or ID of a Docker container. When specified, profiling attaches to a JVM inside this container. |
recordingConfig | object | no | What to record in this session. Every key is optional and omitted keys keep their defaults - set only the keys this analysis needs, such as recordMonitors for lock contention analysis, recordAllocations for allocation sites, triggers for automatic captures during the recording, or advanced.methodCallRecordingType instrumentation when invocation counts are needed. |
Properties of recordingConfig
| Parameter | Type | Required | Description |
|---|---|---|---|
recordAllocations | boolean | no | Record allocation data with call stacks instead of performance data. The two are exclusive because recording both distorts the results. Valuable on its own via the allocation datasets, and a heap dump taken in such a session additionally carries per-object allocation sites (heap.allocation* datasets). Allocation data is sampled, not exact. Default false |
recordMonitors | boolean | no | Also record monitor and lock events: threads blocked on monitors, waiting in Object.wait or parked, with stack traces. Composes with performance and allocation recording and enables the monitor.* datasets for contention, lock-order inversion and deadlock analysis. Default false |
blockingThresholdMicros | integer | no | Optional minimum duration in microseconds for blocked monitor events when 'recordMonitors' is true, shorter events are discarded. Default 1000 |
waitingThresholdMicros | integer | no | Optional minimum duration in microseconds for waiting and parked monitor events when 'recordMonitors' is true, shorter events are discarded. Default 100000 |
subsystems | array of string | no | The subsystems to record in this session. Subsystems not listed are not recorded. Built-in values: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, socket, file, process, gc. Custom probes of the profiled application (embedded or injected probe classes) are recorded as 'custom:<fully qualified probe class name>', e.g. custom:com.example.MyProbe. Script probes are not listed here, they are defined in 'advanced.scriptProbes' and recorded as 'script:<name>'. Default: cpu, jdbc, jpa, mongo_db, cassandra, http_server, http_client, ws, jndi, jms, kafka_consumer, rmi, grpc, ai, process, gc. |
advanced | object | no | Settings that are off by default. Only change them for a concrete reason, never speculatively - more data is not better, and a wrong value can silently lose data. Valid reasons are e.g. check_status reporting possibleInlineAsyncTypes, an application that hands work to thread pools, coroutines or event dispatch threads, an analysis that needs invocation counts, or a previous recording showing that the default filters hide relevant code. The keys without a description correspond to session configuration attributes (such as splittingCap for the call tree split cap mentioned in capped_split warnings) and are documented in the resource jprofiler://config/session. |
triggers | array of object | no | Actions executed automatically when an event occurs during the recording. Use them for conditions that interactive tool calls cannot catch: recordings from JVM start, long-running sessions and transient states like heap spikes, or work scoped to a method with 'methodInvocation'. MBean snapshots and heap dumps captured by triggers become part of the session snapshot and are queried like manually captured ones. Example: {"on": "timer", "intervalSeconds": 60, "actions": [{"type": "mbeanSnapshot"}]} |
Properties of recordingConfig.advanced
| Parameter | Type | Required | Description |
|---|---|---|---|
filter | string | no | Comma-separated list of project packages to profile (e.g. 'com.example.app,org.service'). A wrong package silently excludes relevant code from the recording. |
inlineAsyncTypes | array of string | no | Record async request tracking for the given types, one or more of executor, kotlin_coroutines, awt, swt, virtual_thread, platform_thread. Async executions are then inlined under their call sites in the call tree and hotspot datasets. Off by default because tracking adds overhead - enable when analyzing applications that hand work to thread pools, coroutines or event dispatch threads, or when check_status reports possibleInlineAsyncTypes after a previous recording. |
methodCallRecordingType | string | no | How CPU method calls are recorded. 'sampling' (default) takes periodic call stack samples: very low overhead that does not depend on the package filter, accurate times, but no invocation counts, and methods shorter than the sampling period or called rarely can be missed. 'instrumentation' modifies the bytecode of profiled classes to track method entry and exit: the only mode with exact invocation counts (the count field in the performance datasets) and reliable timing of small, frequently called methods, and it makes allocation stack traces exact; the cost is high overhead and distorted CPU times in CPU-bound code, so it requires a package filter (filter in this object) that restricts instrumentation to the relevant packages. 'async_sampling' samples asynchronously without safepoint bias: the most accurate CPU times for highly multithreaded CPU-bound code, but only on macOS and Linux with a HotSpot JVM (otherwise the agent falls back to sampling), no wall clock times (threadStatus all has no effect) and no invocation counts. Use instrumentation when the analysis needs call counts, otherwise keep the default. One of instrumentation, sampling, async_sampling. |
exceptionalMethods | array of string | no | Methods whose slowest invocations are kept as separate, individually expandable nodes in performance.callTree (marked with exceptionalRun) instead of being merged into the average. Use after performance.outliers shows a method whose maxMicros deviates strongly from its avgMicros. Format: com.foo.Bar.method(long, java.lang.String), exactly as printed in the method field of performance.outliers; the argument list is required, use () for no parameters. Requires methodCallRecordingType 'instrumentation'. Not recorded for virtual threads. |
probeConfig | object | no | Probe-specific settings: a map of subsystem name to a map of attribute name to value, applied to the probe configuration of the recording. Examples: {"jdbc": {"preparedStatementParameters": true}} records prepared statement parameters in the jdbc hotspots, {"http_server": {"split": false}} disables URL call tree splitting of the HTTP server probe, {"http_server": {"splitType": "script", "requestResolvers": ["..."]}} splits the call tree by script-computed request names. Custom probes of the profiled application use the key "custom:<fully qualified probe class name>" with the attributes "events" (record individual events for the probe.events dataset) and "injected" (prepare_profiling and attach pass the probe discovery VM parameter), e.g. {"custom:com.example.MyProbe": {"events": true, "injected": true}} - unknown attributes of custom probes are errors. Script probes defined in 'scriptProbes' use the key "script:<name>" with the attribute "events". Attribute names and values are those of the JProfiler session configuration, the reference with all attributes of all probes is the resource jprofiler://config/probes. Unknown attributes are silently ignored, the applied settings are reported as probeSettings in check_status. |
splitMethods | array of object | no | Split the call tree below the given methods by a script-computed key: each distinct returned string gets its own subtree (type method_split in performance.callTree), for example to analyze request handling per message type. Example: [{"method": "com.example.Handler.onMessage(javax.jms.Message)", "script": "return param0.getJMSType();"}]. Works with any methodCallRecordingType. The script runs on every invocation of the method, so do not split extremely hot methods. The number of distinct keys per split location is capped ('splittingCap', see jprofiler://config/session), further keys are merged into a capped_split node. The script API is documented in the jprofiler://api/method-scripts resource. |
complexityMethods | array of object | no | Measure how the invocation time of the given methods scales with an input size computed per invocation by a script: the complexity.methods dataset then holds the recorded (input size, time) points and curve fits, answering questions like 'is this method O(n^2) in the payload size'. This is the second step after performance.hotspots has identified a suspicious method whose inputs vary in size - re-record with this setting pointing at that method. Example: [{"method": "com.example.Service.process(java.util.List)", "script": "return param0.size();"}]. Works with any methodCallRecordingType. Recording starts with the session and stops before the snapshot is saved; bound the measurement window with startRecording/stopRecording actions ("complexity": true) in triggers or attached_action. The script API is documented in the jprofiler://api/method-scripts resource. |
scriptProbes | array of object | no | Define script probes: lightweight probes declared as scripts, compiled by this server and pushed to the profiled JVM - no code, build or deployment in the profiled application, works on attach. Each probe intercepts the given methods, the script computes the payload string per invocation. Defining a script probe records it: it appears as subsystem 'script:<name>' with payload hot spots in performance.hotspots/callTree; individual events are recorded with 'probeConfig': {"script:<name>": {"events": true}}. Example: [{"name": "Order processing", "methods": [{"method": "com.example.Shop.processOrder(int)", "script": "return "order " + param0;"}]}]. Script probes cannot split the call tree, access return values or create control objects, custom event types or telemetries - for those write a custom probe, see jprofiler://probes/custom. The script API is documented in the jprofiler://api/method-scripts resource. |
scriptClassPath | array of string | no | Additional compile classpath for all scripts in this object ('splitMethods', 'complexityMethods' and script properties in 'probeConfig'): absolute paths to JAR files, to directories containing JAR files, or wildcard patterns like /path/to/lib/*.jar. Only needed when a script references classes beyond the JDK and the JProfiler classes, typically application classes. Used for compilation on this machine only - at runtime the classes must be present in the profiled JVM, which is normally the case for application classes. |
splittingCap | integer | no | Session setting, see the config/session reference. |
exceptionalCap | integer | no | Session setting, see the config/session reference. |
exceptionalTimeType | string | no | Session setting, see the config/session reference. One of all, running, waiting, blocking, netio. |
samplingFrequency | integer | no | Session setting, see the config/session reference. |
samplingNoFilters | boolean | no | Session setting, see the config/session reference. |
lineNumbers | boolean | no | Session setting, see the config/session reference. |
instrumentNativeMethods | boolean | no | Session setting, see the config/session reference. |
recordArrayAlloc | boolean | no | Session setting, see the config/session reference. |
allocationSamplingInterval | integer | no | Session setting, see the config/session reference. |
allocTreeRecordingType | string | no | Session setting, see the config/session reference. One of live, liveAndGcNoClassResolution, liveAndGc. |
utilConcurrentHandling | boolean | no | Session setting, see the config/session reference. |
internalExcludes | boolean | no | Session setting, see the config/session reference. |
libraryDebugParameters | string | no | Session setting, see the config/session reference. |
payloadCap | integer | no | Session setting, see the config/session reference. |
descriptorCap | integer | no | Session setting, see the config/session reference. |
hotspotPayloadCap | integer | no | Session setting, see the config/session reference. |
probeFileMBCap | integer | no | Session setting, see the config/session reference. |
retainStackForHotspotConsolidation | boolean | no | Session setting, see the config/session reference. |
annotateCustomPayloads | boolean | no | Session setting, see the config/session reference. |
samplingPayloadCallStacks | boolean | no | Session setting, see the config/session reference. |
exactSamplingMonitorCallStacks | boolean | no | Session setting, see the config/session reference. |
sampleUnmountedVirtualThreads | boolean | no | Session setting, see the config/session reference. |
asyncThreadResolution | boolean | no | Session setting, see the config/session reference. |
asyncNativeSampling | boolean | no | Session setting, see the config/session reference. |
asyncBufferPercentage | integer | no | Session setting, see the config/session reference. |
Properties of recordingConfig.advanced.splitMethods entries
| Parameter | Type | Required | Description |
|---|---|---|---|
method | string | no | The method below which the call tree is split, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter. |
script | string | no | Java code returning the split key string, or null to leave the invocation unsplit. Available parameters: scriptContext (com.jprofiler.api.agent.ScriptContext, stores per-script state with putObject/getObject and putLong/getLong), clazz (the Class of the declaring class), currentObject (the instance the method is invoked on, null for static methods), param0, param1, ... (the declared method parameters in order). Parameters are statically typed when their class is on the compile classpath and Object otherwise - add application JARs with 'scriptClassPath' to get static typing. |
Properties of recordingConfig.advanced.complexityMethods entries
| Parameter | Type | Required | Description |
|---|---|---|---|
method | string | no | The method whose scaling is measured, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter. |
script | string | no | Java code returning the input size of the invocation as a long, for example 'return param0.size();' for a collection parameter. Same environment as 'splitMethods' scripts (scriptContext, clazz, currentObject, param0, param1, ...). |
Properties of recordingConfig.advanced.scriptProbes entries
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | no | The probe name. The probe is recorded as subsystem 'script:<name>'. |
description | string | no | Optional explanation of the probe's purpose. |
annotatePayloads | boolean | no | Optional: annotate the CPU call tree with the payload strings. Default false. |
methods | array of object | no |
Properties of recordingConfig.advanced.scriptProbes.methods entries
| Parameter | Type | Required | Description |
|---|---|---|---|
method | string | no | The intercepted method, in the format com.foo.Bar.method(long, java.lang.String), with () for no parameters. The method does not have to match the package filter. |
script | string | no | Java code returning the payload string for the invocation, or null for no payload. Same environment as 'splitMethods' scripts (scriptContext, clazz, currentObject, param0, param1, ...). |
Properties of recordingConfig.triggers entries
| Parameter | Type | Required | Description |
|---|---|---|---|
on | string | yes | When the actions run: 'start' when the recording starts (after the optional delay for prepare_profiling, right after attaching for attach), 'stop' when the recording stops (JVM exit, maximumDuration or check_status with stopRecording for prepare_profiling, check_status with stopRecording for attach), 'timer' periodically, 'heapThreshold' when the used heap stays above 'percent' of the maximum heap, 'cpuThreshold' when the CPU usage stays above 'percent'. Threshold triggers fire at most about once a minute while the condition holds. 'methodInvocation' fires when the method given in 'method' is entered; with 'waitForFinish' in the actions, the actions before it run on method entry and the actions after it on method exit. A subsystem started by a method trigger is not started automatically at recording start, so the trigger defines the recording scope. One of start, stop, timer, heapThreshold, cpuThreshold, methodInvocation. |
intervalSeconds | integer | no | Required for 'on': 'timer': the period in seconds. |
offsetSeconds | integer | no | Optional for 'on': 'timer': delay of the first fire in seconds. Default 0. With a 0 offset the first fire can land before the application has registered its MBeans or reached its working state, a small offset like 1 avoids a mostly empty first capture. |
count | integer | no | Optional for 'on': 'timer': fire at most this many times. Default unlimited. |
percent | integer | no | Required for 'heapThreshold' and 'cpuThreshold': the threshold in percent. Choose a high value such as 80, the actions fire every time the condition holds. |
method | string | no | Required for 'on': 'methodInvocation': the method in the format com.foo.Bar.method(long, java.lang.String) as printed by the performance.outliers dataset; the argument list is required, use () for no parameters. Method triggers instrument only the named method and work with any method call recording type, including the default sampling. Recursive calls fire only once per outermost invocation. |
actions | array of object | yes | The actions to run when the event fires, in order. |
Properties of recordingConfig.triggers.actions entries
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | yes | 'mbeanSnapshot': capture the current JMX MBean attribute values into the session snapshot (mbean.snapshots dataset). 'heapDump': take a heap dump that becomes part of the session snapshot (heap.* datasets) - expensive, use it with rare events like 'stop' or a high 'heapThreshold', not with 'timer' or 'start'. 'threadDump': take a thread dump that becomes part of the session snapshot (threads.dumps dataset) - cheap, suitable for 'timer' and threshold triggers. 'monitorDump': capture the currently held and waited-on monitors with the involved threads and stack traces (monitor.current dataset) - only the latest dump is kept, repeated fires overwrite it, so prefer events like 'stop' or thresholds over 'timer'. 'markHeap': mark all current heap objects as old, so a heap dump taken later distinguishes objects allocated afterwards (generation 'new' in the heap.* datasets). 'startRecording'/'stopRecording': start or stop recording of subsystems, at least one of 'cpu', 'allocations', 'monitors', 'probes', 'complexity' is required. 'waitForFinish': only for 'methodInvocation', splits the actions into on-entry and on-exit. 'sleep': wait, delays the following actions. One of mbeanSnapshot, heapDump, threadDump, monitorDump, markHeap, startRecording, stopRecording, waitForFinish, sleep. |
filter | string | no | Optional for 'mbeanSnapshot': regular expression matched against the domain and each property value of the MBean object names: "java.lang|com.mycompany.*" captures all MBeans in those domains, "Memory" the java.lang:type=Memory MBean. Without a filter all MBeans are captured, the right choice for exploration. |
label | string | no | Optional for 'mbeanSnapshot' and 'threadDump': label shown in the mbean.snapshots resp. threads.dumps dataset. In triggers the default is a name derived from the event. |
fullGc | boolean | no | Optional for 'heapDump': run a full GC before the dump so only live objects are captured. Default true. |
includeVirtualThreads | boolean | no | Optional for 'threadDump': take a virtual thread dump that includes all virtual threads and the thread container hierarchy in addition to the platform threads. Default false (platform threads only). Virtual threads require JDK 21+. |
cpu | boolean | no | Optional for 'startRecording'/'stopRecording': include CPU recording. |
allocations | boolean | no | Optional for 'startRecording'/'stopRecording': include allocation recording. |
monitors | boolean | no | Optional for 'startRecording'/'stopRecording': include monitor recording. |
complexity | boolean | no | Optional for 'startRecording'/'stopRecording': include complexity recording - requires recordingConfig.advanced.complexityMethods in the same session. Use it to bound the measurement window, for example scoped to a method with a methodInvocation trigger, or to exclude a warmup phase. |
probes | array of string | no | Optional for 'startRecording'/'stopRecording': probe names to start or stop, e.g. ["jdbc"], "custom:<fully qualified probe class name>" for custom probes of the profiled application, or "script:<name>" for a script probe defined in recordingConfig.advanced.scriptProbes. |
seconds | integer | no | Required for 'sleep': the wait time in seconds. |
check_status
Check the status of a profiling session and discover which subsystems were recorded. Can be used to stop recording. When the data is ready provides information about the recorded subsystems (e.g. cpu, jdbc, http_client).
| Parameter | Type | Required | Description |
|---|---|---|---|
stopRecording | boolean | no | Optionally request the recording to be stopped now. |
query
Query a performance or heap dataset with a jq expression and return the result. The dataset is materialized lazily and cached per session. Each query is independent, there is no current object: builtins take explicit ids bound from earlier results, e.g. .instances[0].id as $id | {value: preview($id), keptAliveBy: pathToRoot($id).paths[0].path | map(.class)}
| Parameter | Type | Required | Description |
|---|---|---|---|
dataset | string | yes | The dataset to query. The jprofiler://datasets resource documents all datasets with arguments, row formats and examples, check_status lists them with availability for the current session. One of performance.hotspots, performance.callTree, allocation.hotspots, allocation.callTree, heap.classes, heap.biggestObjects, heap.instances, heap.sizes, heap.objectCounts, heap.inspections, heap.inspectionResult, heap.allocationHotspots, heap.allocationCallTree, telemetry.list, telemetry.series, monitor.stats, monitor.timeline, monitor.history, monitor.graph, monitor.current, mbean.snapshots, performance.outliers, threads.list, threads.dumps, probe.events, probe.eventHistogram, probe.eventTimeline, probe.controlObjects, gc.collections, javascript.origins, complexity.methods. |
subsystem | string | no | The subsystem to analyze, a value from availableSubsystems in check_status (e.g. cpu, jdbc). If the session recorded a single subsystem it is used automatically |
threadStatus | string | no | Optional for performance datasets: the thread state whose time is counted. 'running' (default for cpu) counts only time while the thread is scheduled by the OS, waiting on sockets, locks or other threads is not included. 'all' (default for probes) counts wall clock time in all states. 'net_io' counts time waiting on network or file I/O, the state of slow database or REST calls. 'waiting' and 'blocked' count time waiting on other threads or blocked on a monitor, for inter-thread handoff and lock contention analysis. Only 'all' and 'running' carry invocation counts for cpu. Not available for JFR probe subsystems. One of all, running, waiting, blocked, net_io. |
metric | string | no | Optional for performance datasets of probe subsystems that record a size or token measurement (file, socket, AI): the measurement the hotspots and call tree are ranked by. 'duration' (default) measures event durations, the alternatives are listed in the probeMetrics section of check_status (e.g. write_throughput). Value properties in the result are then named by the metric unit (bytes, tokens) instead of micros. Cannot be combined with threadStatus |
aggregation | string | no | Optional for performance and allocation datasets: the rollup level of the tree nodes. 'method' (default) aggregates per method, 'class' per class, 'package' per package, 'component' by Spring, JEE and JPA component class (controllers, services, repositories, empty for apps without such components). Class, package and component rollups are exact, they include everything below the row cutoffs of the method view, and they shrink huge deep trees to an overview. Drill back in with 'method' and a packageFilter. One of method, class, package, component. |
thread | string or integer | no | Optional for performance datasets: restrict the analysis to selected threads. 'all' (default) merges all threads, 'virtual' merges all virtual threads into one, an integer thread id selects a single thread - use a threadId from threads.list rows (the same ids the monitor datasets use). Cannot be combined with threadGroup |
threadGroup | string | no | Optional for performance datasets: restrict the analysis to one thread group, a group value from threads.list rows (platform threads only, virtual threads have no groups). Cannot be combined with thread |
packageFilter | string or array | no | Optional package filter to focus on classes of interest (heap datasets and performance subsystems), comma-separated or as a JSON array |
payloadFilter | string or array | no | Optional filter on payload descriptions (SQL statements, URLs) for probe subsystems, applied to hotspots and call trees before the row cutoffs. Each pattern keeps descriptions that contain it, case-sensitive, * and ? are literal characters (a lone * means no filter), comma-separated or as a JSON array, a pattern with a comma needs the array form |
class | string | no | Required for heap.instances: the class to list instances of, a name value from heap.classes (after the first query, omitting it continues with the last used class) |
limit | integer | no | Optional row limit for heap.instances, javascript.origins, monitor.history and threads.list, the defaults and caps are documented per dataset in the check_status catalog |
field | string | no | Optional value filter on heap.instances: a field path like customer.name or orders[].id |
op | string | no | The filter operation for field: string comparisons (contains, startsWith, endsWith, equals, regexp), object fields (null, nonNull), numeric equals or a from/to range. One of contains, startsWith, endsWith, equals, regexp, null, nonNull. |
value | string | no | The comparison value for field and op |
from | number | no | Inclusive lower bound for a numeric range filter or the start of the time window in seconds since recording start (telemetry.series, monitor.*) |
to | number | no | Inclusive upper bound for a numeric range filter or the end of the time window in seconds since recording start (telemetry.series, monitor.*) |
ignoreCase | boolean | no | Ignore case for string comparisons, default false |
generation | string | no | Optional on heap.classes, heap.biggestObjects and heap.instances: restrict to objects allocated after (new) or before (old) the last markHeap action of the recorded session. One of new, old. |
filterScript | string | no | Optional for heap.instances and heap.sizes: a Java script evaluated per object, keeping objects where it returns true - for predicates the value filter cannot express. Read the jprofiler://api/heap-scripts resource for the script API before writing a script |
filterPath | string | no | Optional with filterScript: a field path like customer.name or orders[].id, the script is evaluated on the objects the path navigates to instead of the instances of the class |
groupScript | string | no | Required for the custom_grouping inspection: a Java script evaluated per object that returns the group key string, null skips the object. Read the jprofiler://api/heap-scripts resource for the script API before writing a script |
set | integer | no | Optional for heap.instances, heap.sizes and heap.inspectionResult: a set value from a previous heap result, the operation runs on that object set instead of a class or the whole heap; class, packageFilter and the value filter cannot be combined, filterScript and generation still apply |
inspection | string | no | Required for heap.inspectionResult: the inspection to run, an id from heap.inspections. One of self_referencing_objects, retained_by_inner_class, many_incoming_references, null_fields, duplicate_strings, duplicate_primitive_wrappers, duplicate_arrays, sparse_arrays, zero_length_arrays, thread_local, stack_referenced, weakly_referenced, duplicate_classes, group_instances_by_loader, group_classes_by_loader, hash_map_distribution, custom_grouping. |
telemetry | string | no | Required for telemetry.series: the telemetry to fetch, an id from telemetry.list (e.g. heap, cpu, threads, heap/PS Eden Space, gc/G1 Young Generation, custom/<name>, jdbc/<group>) |
line | string | no | Optional for telemetry.series: restrict the series to one line by name |
maxPoints | integer | no | Optional for telemetry.series and monitor.timeline: number of consolidated points per line, default 120, max 500 |
groupBy | string | no | Optional for monitor.stats: the aggregation grouping, default monitors. One of monitors, threads, classes. |
eventType | string | no | Optional for monitor.history: restrict to one event type. One of blocked, waiting, parked. |
monitorId | integer | no | Optional for monitor.history and monitor.graph: restrict to one monitor id from monitor.stats |
threadId | integer | no | Optional for monitor.history and monitor.graph: restrict to one waiting or owning thread id from monitor.stats |
minDurationMicros | integer | no | Optional for monitor.history: minimum event duration in microseconds |
minMaxMicros | integer | no | Optional for performance.outliers: only methods whose slowest invocation took at least this many microseconds, default 10000 |
minCount | integer | no | Optional for performance.outliers: only methods with at least this many invocations, default 10 |
snapshot | integer | no | Optional for mbean.snapshots: the index of an MBean snapshot from the catalog |
name | string | no | Optional for mbean.snapshots: an MBean object name, requires the snapshot argument |
text | string | no | Optional for probe.events and probe.controlObjects: text filter matched against the event description and all text payloads or the object name and text properties, comma-separated alternatives, matching per matchMode |
matchMode | string | no | Optional for probe.events and probe.controlObjects: how text is matched, default contains. One of contains, startsWith, endsWith, equals, wildcard, regex. |
controlObjectId | integer | no | Optional for probe.events: restrict to the events of one control object, a controlObjectId from probe.controlObjects or probe.events rows |
state | string | no | Optional for probe.controlObjects: 'open' (default) lists only objects still open, 'closed' only closed objects, 'all' both, 'collectedWithoutClose' (only jdbc with leak recording) connections that were garbage collected without close. One of open, closed, all, collectedWithoutClose. |
maxObjects | integer | no | Optional for probe.controlObjects: maximum number of objects per state, default 200, max 2000 |
types | string or array | no | Optional for probe.events: event type names to include, comma-separated or as a JSON array, e.g. the type values of previous rows (open/close names or probe-specific names like 'Statement execution') |
sort | string | no | Optional for probe.events: the global selection and output order - 'duration' (default) keeps and returns the slowest events, 'startTime' the most recent ones. One of duration, startTime. |
maxEvents | integer | no | Optional for probe.events: page size of the global top-N selection, default 1000, max 10000 |
minMicros | integer | no | Optional for probe.events: minimum event duration in microseconds |
maxMicros | integer | no | Optional for probe.events: maximum event duration in microseconds |
column | string | no | Optional for probe.eventHistogram: the measured value, 'duration' (default), 'throughput' for file/socket probes, or a numeric payload property name from probe.events rows |
maxBuckets | integer | no | Optional for probe.eventHistogram: maximum bucket count, default 100, max 1000 - the histogram adapts its bucket size to stay below |
scope | string | no | Optional for javascript.origins: 'recorded' (default) lists only the origins whose requests reached the profiled application, 'all' every origin the browser extension reported, with a recorded flag per row. One of recorded, all. |
id | integer | no | The expansionId of a row from a previous hotspots, callTree, allocation, probe.events, probe.controlObjects or threads.dumps query for the expand dataset, or the id of a biggest object from heap.biggestObjects for the retained dataset |
expression | string | yes | The jq expression, passed as a plain JSON string without surrounding quotes. . returns the dataset unchanged. Datasets are objects, the rows are in the hotspots, callTree, classes or biggestObjects array. Filtering, sorting, projection and aggregation belong in the expression. Examples: .hotspots | sort_by(-.percent) | .[0:10], .hotspots | map({method, percent, expansionId}) | .[0:5] (keep expansionId for drill-downs) or .hotspots | group_by(.method | split(".")[0]) | map({pkg: .[0].method, hotspots: length}) (delivered rows only, exact rollups of the complete recording come from the aggregation parameter). Project tree rows one level at a time: .callTree | map({method, micros, children: [(.children // [])[] | .method]}) - children and callers are omitted on leaves and omitted arrays cannot be iterated, and multi-step values in an object construction must be wrapped in parens: {key: (expr | filter)}. Drill down with the builtin expand(expansionId) inline: .hotspots | sort_by(-.percent) | .[0] | {method, callers: expand(.expansionId).callers}. Retained classes of a biggest object with the builtin retained(id): .biggestObjects | sort_by(-.retainedSize) | .[0] | {class, retained: retained(.id).classes}. Combined size analysis of an object set with the builtin sizes([ids]): .biggestObjects | {top: .[0:3] | map(.class), sizes: sizes([.[0:3][].id])}. References of a heap object with the builtins incoming(id)/outgoing(id): .instances[0] | {name, heldBy: incoming(.id).referrers | map(.class)}. GC root paths with pathToRoot(id) and value previews with preview(id): .instances[0] | {name, value: preview(.id), keptAliveBy: pathToRoot(.id).paths[0].path | map(.class)}. Capture the input before binding variables: . as $rows | ((map(.micros) | add) as $t | ...), wrap generators in constructions with [...]. Keep results small: project fields and slice with .[0:N]. |
args | object | no | Arguments for parametric datasets, see the jprofiler://datasets resource or the datasets list in check_status |
limitBytes | integer | no | Optional byte budget for the result, default 24000. Larger results are truncated and marked as such |
Properties of args
| Parameter | Type | Required | Description |
|---|---|---|---|
subsystem | string | no | |
threadStatus | string | no | |
metric | string | no | |
aggregation | string | no | |
thread | string or integer | no | |
threadGroup | string | no | |
packageFilter | string or array | no | |
payloadFilter | string or array | no | |
class | string | no | |
limit | integer | no | |
field | string | no | |
op | string | no | |
value | string | no | |
from | number | no | |
to | number | no | |
ignoreCase | boolean | no | |
generation | string | no | |
filterScript | string | no | |
filterPath | string | no | |
groupScript | string | no | |
set | integer | no | |
inspection | string | no | |
telemetry | string | no | |
line | string | no | |
maxPoints | integer | no | |
groupBy | string | no | |
eventType | string | no | |
monitorId | integer | no | |
threadId | integer | no | |
minDurationMicros | integer | no | |
minMaxMicros | integer | no | |
minCount | integer | no | |
snapshot | integer | no | |
name | string | no | |
text | string | no | |
matchMode | string | no | |
controlObjectId | integer | no | |
state | string | no | |
maxObjects | integer | no | |
types | string or array | no | |
sort | string | no | |
maxEvents | integer | no | |
minMicros | integer | no | |
maxMicros | integer | no | |
column | string | no | |
maxBuckets | integer | no | |
scope | string | no | |
id | integer | no |
create_heap_dump
Dump the heap of a locally running JVM or of a JVM inside a Docker container and load it for analysis. If allocation data is recorded for the JVM, the heap dump includes per-object allocation data. A recording session delivers a single heap dump, for a later dump attach again. You must call check_status to check the loading progress and - after this returns 'data_ready' - retrieve data with the query tool. You can use list_jvms to discover JVMs.
| Parameter | Type | Required | Description |
|---|---|---|---|
pid | integer | no | The PID of a local JVM process, or the container PID (NSpid) of a JVM inside the specified container. If a container is specified and this is omitted, the topmost JVM in the container is used. |
containerNameOrId | string | no | The name or ID of a Docker container. When specified, profiling attaches to a JVM inside this container. |
attached_action
Perform a point-in-time action on the connected JVM: thread and monitor dumps, heap marking and heap dumps, MBean snapshots, and starting or stopping subsystem recording. Requires a recording session started with attach or prepare_profiling. The action names and parameters are the same as for the actions of recordingConfig.triggers.
| Parameter | Type | Required | Description |
|---|---|---|---|
action | string | yes | The action to perform on the attached JVM. 'threadDump': the current state and stack trace of every thread, grouped like in the JProfiler thread dumps view - use it when the app is slow but CPU usage is low, and take two dumps to find threads stuck at the same stack trace. 'monitorDump': the currently held and waited-on monitors with the involved threads and stack traces, plus deadlock detection over the current wait/own graph - deadlocks never appear in recorded monitor history because deadlocked events never finish, this dump is the way to find them, and no monitor recording is needed for it; attach-mode dumps show java.util.concurrent locks only, not intrinsic (synchronized) monitors. 'markHeap': mark all current heap objects as old, objects allocated afterwards count as new in heap dumps taken later in this session (generation argument of the heap datasets) - use it to bracket an operation of interest. 'mbeanSnapshot': capture the current JMX MBean attribute values into the session snapshot, for exploration usually unfiltered. 'heapDump': take a heap dump that becomes part of the session snapshot while the recording keeps running - expensive on large heaps, use create_heap_dump instead to stop the recording and analyze the heap immediately. 'startRecording'/'stopRecording': start or stop the recording of subsystems in this session, at least one of 'cpu', 'allocations', 'monitors', 'probes', 'complexity' is required - this does not end the session, use check_status with stopRecording for that. Dumps and snapshots taken by these actions become part of the session snapshot and are served by the threads.dumps, monitor.current, mbean.snapshots and heap.* datasets after the recording is stopped. For captures at events or from JVM start, configure actions with the same names in recordingConfig.triggers of attach or prepare_profiling. One of threadDump, monitorDump, markHeap, mbeanSnapshot, heapDump, startRecording, stopRecording. |
includeVirtualThreads | boolean | no | Optional for 'threadDump': take a virtual thread dump that includes all virtual threads and the thread container hierarchy in addition to the platform threads. Default false (platform threads only). Virtual threads require JDK 21+. |
label | string | no | Optional for 'mbeanSnapshot' and 'threadDump': label shown in the mbean.snapshots resp. threads.dumps dataset. In triggers the default is a name derived from the event. |
filter | string | no | Optional for 'mbeanSnapshot': regular expression matched against the domain and each property value of the MBean object names: "java.lang|com.mycompany.*" captures all MBeans in those domains, "Memory" the java.lang:type=Memory MBean. Without a filter all MBeans are captured, the right choice for exploration. |
fullGc | boolean | no | Optional for 'heapDump': run a full GC before the dump so only live objects are captured. Default true. |
cpu | boolean | no | Optional for 'startRecording'/'stopRecording': include CPU recording. |
allocations | boolean | no | Optional for 'startRecording'/'stopRecording': include allocation recording. |
monitors | boolean | no | Optional for 'startRecording'/'stopRecording': include monitor recording. |
probes | array of string | no | Optional for 'startRecording'/'stopRecording': probe names to start or stop, e.g. ["jdbc"], "custom:<fully qualified probe class name>" for custom probes of the profiled application, or "script:<name>" for a script probe defined in recordingConfig.advanced.scriptProbes. |
complexity | boolean | no | Optional for 'startRecording'/'stopRecording': include complexity recording - requires recordingConfig.advanced.complexityMethods in the same session. Use it to bound the measurement window, for example scoped to a method with a methodInvocation trigger, or to exclude a warmup phase. |
list_jvms
List locally running JVMs or JVMs running in a Docker container with their command line and PID. Use the information to call attach or create_heap_dump.
| Parameter | Type | Required | Description |
|---|---|---|---|
containerNameOrId | string | no | Optionally specify the name or ID of a Docker container. |
Resources
Resources are read-only documents served by the MCP server. An agent reads them at runtime when it needs the details, for example the script API reference before writing a heap script or the probe configuration reference before tuning a recording. The full content of each resource is also published here:
jprofiler://datasets: All datasets of the query tool and the jq builtins for the query expression, with arguments, row formats and examples. Static reference, check_status reports the session-specific catalog with availability flags. (full reference)jprofiler://config/session: All session settings usable as direct keys of recordingConfig.advanced of the prepare_profiling and attach tools, with types, defaults and explanations (full reference)jprofiler://config/probes: All probe attributes usable in recordingConfig.advanced.probeConfig of the prepare_profiling and attach tools, with types, defaults and explanations (full reference)jprofiler://probes/custom: Custom probes of the profiled application: what they are, embedded vs injected, when not to write one, build setup, deployment and recording as custom:<fully qualified probe class name> subsystems. Read this before recording or writing a custom probe. (full reference)jprofiler://api/method-scripts: Script API of recordingConfig.advanced.splitMethods and complexityMethods: the script contract, the available parameters and the ScriptContext state store. Read this before writing a split or complexity script. (full reference)jprofiler://api/heap-scripts: Java script API for the filterScript parameter of heap.instances and heap.sizes and the groupScript parameter of the custom_grouping inspection: script signatures, the heap object model and limitations. Read this before writing a heap script. (full reference)jprofiler://api/controller: API reference of com.jprofiler.api.controller.Controller: the profiled application drives profiling itself - start/stop recordings, save snapshots, heap dumps, heap marks and bookmarks from application code. Read this when the application knows better than the agent when to record. (full reference)jprofiler://api/probe-embedded: API reference of com.jprofiler.api.probe.embedded for embedded custom probes: the probe base classes PayloadProbe and SplitProbe, the measurement entry points Payload and Split and the telemetry annotations. Read this before writing an embedded probe. (full reference)jprofiler://api/probe-injected: API reference of com.jprofiler.api.probe.injected for injected custom probes: the @Probe annotation, the interception declarations, the injected parameter annotations and the telemetry annotations. Read this before writing an injected probe. (full reference)
Server instructions
When an agent connects to the MCP server, it receives the following instructions that describe the recommended workflows:
Workflow Rules for performance recording: Setup: For profiling a new Java process, call prepare_profiling to get the required JVM parameter. For attaching to a running JVM, call attach. Both create live sessions that support attached_action while recording. Finishing a recording saves a snapshot and disconnects. For another recording on the same JVM, call attach with its PID. prepare_profiling tokens are single-use startup parameters. If the user has a complex scenario, suggest they manually record a .jps file in JProfiler and use load_snapshot instead. If the application itself should drive recording (for example saving a snapshot when a rare error occurs), the Controller API for application code is documented in the jprofiler://api/controller resource. Use check_status to check for data availability.
Discovery and drill-down: Once data is available, call check_status to see the datasets list, then use query to retrieve and analyze them. Filtering, sorting, projection and aggregation belong in the jq expression, not in repeated tool calls. Keep results small by projecting fields and slicing with .[0:N], oversized results are truncated and marked as such. For back traces and call tree children, use the expand(expansionId) jq builtin inline in the expression.
Thread states: the default running view hides time spent waiting. When CPU usage is low but the app is slow, re-query with threadStatus "all" (wall clock time), or "net_io" for database and REST wait and "blocked"/"waiting" for lock and inter-thread analysis.
Threads: performance datasets merge all threads by default. When the question targets a specific thread or a thread pool, find it in the threads.list dataset (each row carries the per-state time breakdown), then pass its threadId as the thread parameter, a group name as threadGroup, or thread "virtual" for all virtual threads. To find out which threads contribute to a cpu hotspot or call tree node, pass its expansionId to the threads(expansionId) jq builtin. Combine with threadStatus to see where the selected threads spend waiting or blocked time.
Invocation counts: sampling produces no invocation counts. If the analysis needs call counts (how often a method was invoked), re-record with "recordingConfig": {"advanced": {"methodCallRecordingType": "instrumentation", "filter": "<application packages>"}}.
Exceptional invocations: when the question is why a call is occasionally slow, record with instrumentation, query performance.outliers for methods whose maxMicros deviates strongly from avgMicros, then re-record with the method copied into "recordingConfig": {"advanced": {"exceptionalMethods": [...]}} and expand the nodes marked exceptionalRun in performance.callTree to inspect single slow invocations. The outlier times are measured in the thread status reported as threadStatus in the result (all = wall clock), set "recordingConfig": {"advanced": {"exceptionalTimeType": "waiting"}} when re-recording to analyze a different thread state.
Workflow Rules for heap dump analysis: Setup: Use load_snapshot to load an existing HPROF or JPS snapshot or use create_heap_dump to dump the heap of a running JVM. Use check_status to check for data availability.
Discovery: Once data is available, call check_status to see the datasets list, then use query to retrieve and analyze the heap dump (class histogram, biggest objects, instances). Use the retained(id), incoming(id), outgoing(id), pathToRoot(id), preview(id), referrersByClass(id) and referencesByClass(id) jq builtins with object ids to follow the object graph. Heap datasets are not available for snapshot comparisons.
Heap scripts: filtering beyond the value filter and grouping by computed keys are done with Java scripts - the filterScript parameter of heap.instances and heap.sizes and the custom_grouping inspection of heap.inspectionResult. Read the jprofiler://api/heap-scripts resource for the script API before writing a heap script.
Workflow rules for probe events: Probe subsystems (jdbc, http_server, ...) record aggregated hot spots by default; individual events (single SQL statements, HTTP requests, ...) require event recording: "recordingConfig": {"advanced": {"probeConfig": {"<subsystem>": {"events": true}}}}, or a snapshot recorded with events. The probeEvents section of check_status lists the subsystems with recorded events. probe.events serves the individual events: its arguments filter and select globally over the full event set, the jq expression only sees the returned page - use matchedCount to judge selectivity and narrow with from/to, minMicros, types or text. probe.eventTimeline localizes bursts in time, probe.eventHistogram estimates the duration distribution and percentiles. Rows with an expansionId have a back trace for expand(expansionId). Probes with open/close resources (jdbc connections, files, sockets, processes) also record control objects: probe.controlObjects lists the still open objects oldest first, the leak analysis entry point - expand the openExpansionId of a leak candidate for the stack trace of the open call, the probeControlObjects section of check_status lists the subsystems with control objects, most probes have none. Beyond the fixed set of built-in probes, probes written for the profiled application are recorded as custom:<fully qualified probe class name> subsystems - read the jprofiler://probes/custom resource first. Probes declared as scripts in recordingConfig.advanced.scriptProbes need no deployment and appear as script:<name>.
Workflow rules for GC data: The gc subsystem records JFR garbage collection data. Recordings started through this server include it by default; in snapshots recorded elsewhere it depends on the source - the JProfiler UI only collects GC data while GC recording was active, JFR files carry GC events in most configurations. The snapshotInfo.gcInfo block of check_status appears when GC data exists and holds the aggregate pause and collection statistics and the collector configuration, the gc.collections dataset serves the individual collections: cause, pause times, phases, reference counts and heap/metaspace usage before and after each GC, plus the GC flags and the full configuration in the header. Find pause outliers with sort_by(-.longestPauseMicros), explain a long pause with its cause and phases, follow the leak slope in heapUsedAfterBytes. GC collections carry no back traces, correlate causes like "G1 Humongous Allocation" with the allocation datasets.
Workflow rules for lock and monitor analysis: Lock contention is invisible in CPU data, threads blocked on a lock burn no CPU. Record monitors by passing "recordingConfig": {"recordMonitors": true} on attach or prepare_profiling, or load a snapshot that contains monitor recording. Start with the monitor.stats dataset to find the monitors, threads or classes with the most lost time, use monitor.timeline to locate contention bursts in time, then drill into monitor.history for individual locking situations with stack traces and monitor.graph for lock-order inversions. When the question is whether a live JVM is deadlocked right now, call attached_action with action monitorDump in a live session; attach-mode dumps show java.util.concurrent locks only, not intrinsic (synchronized) monitors.
Workflow rules for thread dumps: A thread dump captures the state and stack trace of every thread at one point in time. In a live session, call attached_action with action threadDump (with includeVirtualThreads for the virtual thread population and its container hierarchy). For recordings from JVM start or captures at events like CPU or heap thresholds, configure threadDump actions in recordingConfig.triggers. After the recording is stopped, the threads.dumps dataset lists the captured dumps and expand(expansionId) returns the grouped thread tree of a dump, where threads with identical stack traces collapse into one group. Sort groups by count to find where a large thread population is parked, compare two dumps to find threads stuck at the same stack trace. Thread dumps carry no lock ownership data, for deadlocks and lock analysis use attached_action with action monitorDump and the monitor datasets.
Workflow rules for MBean data: In a live session, call attached_action with action mbeanSnapshot to capture the current JMX MBean attribute values into the session snapshot, for exploration usually unfiltered, labeled when taking a series. For recordings from JVM start, periodic captures or captures at events like heap thresholds, configure mbeanSnapshot actions in recordingConfig.triggers of attach or prepare_profiling instead. After the recording is stopped, the mbean.snapshots dataset serves the captured snapshots: catalog, MBean names per snapshot, attribute values per MBean. MBean values recorded continuously as custom telemetries are in the telemetry.list dataset.
Workflow rules for live actions: In a live session, the attached_action tool performs point-in-time actions on the live JVM. markHeap marks all current heap objects as old, so a heap dump taken later distinguishes objects allocated afterwards. heapDump takes a heap dump into the session snapshot without stopping the recording, use create_heap_dump instead to stop and analyze the heap immediately. startRecording and stopRecording start or stop the recording of subsystems like cpu or monitors in the running session, they do not end the session.