# JFR FAQ:

# 1.Should I use on-prem or cloud to analyze the JFR recordings?

Both options are fully supported, and the choice comes down to your organization's requirements. The cloud version offers the fastest way to get started with no setup required, while the on-premise version is recommended if your organization has security, compliance, or data residency policies that restrict sending diagnostic data outside your infrastructure.

If an on-premise deployment is the right fit for your environment, you can download and set it up using the guide here (opens new window)


# 2. Why am I getting a "File size is too large" error when uploading a JFR recording?

This happens when the .jfr file exceeds the allocated max heap size limit [ie. -xmx value]. JFR file size grows with recording duration, event rate, and which event categories are enabled (especially jdk.ExecutionSample, allocation profiling, or lock contention events at high rates). Below are the ways to overcome this problem:

  • If you are analyzing JFR recording through yCrash cloud, then download the on-prem version and use the JFR player on your premises with a larger heap memory size(-Xmx). Here is the download (opens new window) to set up on-prem.
  • If already using the on-prem version, then increase your heap memory size, i.e, -Xmx.

# 3. What async-profiler arguments are available for JFR profiling, and when should I use them?

async-profiler can output directly in JFR format using -e (event type) and -f (output file) flags. Common event types include cpu (CPU profiling), alloc (allocation profiling), lock (lock contention), and wall (wall-clock profiling for I/O-bound issues). Use CPU profiling for high-CPU troubleshooting, allocation profiling for memory/GC pressure investigations, and lock profiling for contention/deadlock suspicion. Here is the detailed blog about arguments (opens new window).


# 4. Can capturing a JFR recording cause a production application to slow down or crash, even though JFR is designed to have minimal overhead?

JFR's default configuration is built for continuous low-overhead production use - typically well under 1-2% CPU overhead. However, "minimal overhead" isn't guaranteed in every situation. Overhead can spike if:

  • The JVM is already under severe memory or GC pressure (JFR needs to allocate buffers)
  • You've enabled high-frequency events (e.g., allocation profiling at every allocation, or very short sampling intervals)
  • The application is already close to resource exhaustion, so even a small additional load pushes it over the edge

A crash coinciding with JFR capture is more likely to indicate the application was already in a fragile state, and JFR's overhead was the last straw rather than the primary cause. Reviewing GC logs and memory usage from just before the JFR-triggered crash can help confirm this. If you've seen repeated crashes tied to JFR capture, it's worth sharing the recording settings and system state at the time of capture - that's usually diagnosable.


# 5. Are there JFR flags or configuration options that reduce CPU overhead while still capturing useful diagnostic data?

Yes. A few levers:

  • Use the default or profile JFR settings templates rather than custom configs with aggressive thresholds - the default template is tuned for continuous production use.

  • Increase sampling intervals for stack traces (e.g., jdk.ExecutionSample threshold) rather than sampling every method entry.

  • Disable high-volume events you don't need, such as detailed allocation tracking, if you only care about CPU or lock contention.

  • Avoid very short collection intervals (e.g., every minute) for full recordings - instead, use a continuous rolling buffer (-XX:StartFlightRecording=disk=true,maxsize=...,maxage=...) and dump the buffer only when needed, rather than starting/stopping a new recording every minute.

  • Tune stackdepth down if deep stack traces aren't needed for your analysis.

Repeatedly starting and stopping recordings adds more overhead than one continuous low-overhead recording with a rolling buffer.


# 6. How is JFR different from heap dumps, thread dumps, top -H, and GC logs?

Tool What it captures When
Heap dump Snapshot of all objects on the heap at one instant Single point in time
Thread dump Snapshot of all thread states/stacks at one instant Single point in time
top -H OS-level per-thread CPU/memory usage Continuous, but no JVM-level context (no stack traces, no GC/lock detail)
GC logs Every GC event over time Continuous, GC-only
JFR CPU samples, GC events, lock contention, allocations, I/O, thread states, and more - all correlated on one timeline Continuous, over a time window

The key difference is that JFR gives you a continuous, correlated timeline across many subsystems (threads, GC, locks, I/O, exceptions), whereas heap/thread dumps are single snapshots and GC logs cover only garbage collection. JFR won't fully replace a heap dump if you need to inspect actual object contents and references, but for behavior over time - especially intermittent issues - it captures far more context than dumps or GC logs alone.


# 7. If JFR is already capturing thread activity and GC events, are separate thread dumps and GC logs redundant?

Mostly, but not entirely.

  • GC logs vs. JFR GC events: JFR's GC events are generally sufficient and often more convenient, since they're correlated with everything else on the same timeline. Standalone GC logs are still useful if you need a lightweight, always-on record independent of JFR sessions.

  • Thread dumps vs. JFR thread data: JFR samples thread states periodically rather than capturing a complete stack for every thread at an exact instant. If you need the precise, full state of every thread at one specific moment (e.g., to confirm a deadlock), a traditional thread dump is still more definitive. JFR's jdk.ThreadDump event (available in newer JDKs) narrows this gap, but it's worth confirming your JDK version supports it.


# 8. Should JFR analysis be run continuously on production, only when an issue occurs, or during lab performance testing?

All three have a role:

  • Lab/performance testing: Run JFR during load tests to establish a baseline and catch issues before they reach production.

  • Continuous production monitoring: A low-overhead, always-on rolling recording (disk-backed, with size/age limits) is a good safety net - you can dump the buffer retroactively when something goes wrong.

  • On-demand, issue-triggered: For deeper investigation of a known problem, start a more detailed recording with additional event types enabled while the issue is reproducing.

For multi-instance/pod environments, yCrash's script can connect to multiple pods under a service and collect JFR (along with other diagnostics) from each in one pass - this is useful for continuous or issue-triggered collection across a fleet without manually connecting to each instance.


# 9. If I upload the same file today and again a month from now, will I get the exact same AI summary?

Coming soon.