---
name: jfr-profiling
description: >-
  Runs a JFR (Java Flight Recorder) profiling session on a specified target.
  Use when the user asks to "profile this", "run JFR", "profile CPU", "profile allocations",
  "take a flight recording", or "find hot methods".
allowed-tools: "Read, Bash, Write, Grep, Glob"
argument-hint: "[cpu|alloc|wall] [duration-seconds]"
---

JFR profiling quick-action for Java/Kotlin projects.

## Inputs

Read `.codeflash/setup.md` for build tool, JDK version, project root, test command.

Parse arguments: first positional is the profile type (`cpu`, `alloc`, or `wall` — default `cpu`), second positional is duration in seconds (default `60`).

## For `cpu` (or no arguments)

1. Detect a suitable test command from setup.md (Maven `mvn test`, Gradle `./gradlew test`, or a specific test class).
2. Run JFR CPU profiling:
   ```bash
   # For Maven projects:
   mvn test -pl <module> -Dtest=<test> \
     -DargLine="-XX:StartFlightRecording=filename=/tmp/cpu.jfr,duration=<duration>s,settings=profile"

   # For Gradle projects:
   ./gradlew test --tests <test> \
     -Dorg.gradle.jvmargs="-XX:StartFlightRecording=filename=/tmp/cpu.jfr,duration=<duration>s,settings=profile"

   # Or attach to a running process:
   jcmd <PID> JFR.start filename=/tmp/cpu.jfr duration=<duration>s settings=profile
   ```
3. Wait for the recording to complete, then extract top methods:
   ```bash
   jfr print --events jdk.ExecutionSample --stack-depth 5 /tmp/cpu.jfr 2>/dev/null | \
     grep -E "^\s+[a-z]" | sort | uniq -c | sort -rn | head -20
   ```
4. Print a ranked target list with sample counts and percentages.
5. Write results to `.codeflash/jfr-profile.md`.

## For `alloc`

1. Same setup detection as CPU.
2. Run JFR allocation profiling:
   ```bash
   # For Maven projects:
   mvn test -pl <module> -Dtest=<test> \
     -DargLine="-XX:StartFlightRecording=filename=/tmp/alloc.jfr,duration=<duration>s,settings=profile"

   # Or attach to a running process:
   jcmd <PID> JFR.start filename=/tmp/alloc.jfr duration=<duration>s settings=profile
   ```
3. Wait for completion, then extract top allocators:
   ```bash
   jfr print --events jdk.ObjectAllocationInNewTLAB,jdk.ObjectAllocationOutsideTLAB \
     --stack-depth 5 /tmp/alloc.jfr | head -200
   ```
4. Parse and rank allocation sites by total bytes allocated.
5. Print an allocation summary with class names, byte counts, and percentages.
6. Write results to `.codeflash/jfr-profile.md`.

## For `wall`

1. Check if async-profiler (`asprof`) is available on PATH.
2. If async-profiler is available:
   ```bash
   # Start the target process, capture its PID, then:
   asprof -d <duration> -e wall -f /tmp/wall.html <PID>
   ```
   Parse the flame graph text output for top frames.
3. If async-profiler is NOT available, fall back to JFR wall-clock approximation using `jdk.ThreadSleep` and `jdk.ThreadPark` events:
   ```bash
   mvn test -pl <module> -Dtest=<test> \
     -DargLine="-XX:StartFlightRecording=filename=/tmp/wall.jfr,duration=<duration>s,settings=profile"

   jfr print --events jdk.ThreadPark,jdk.ThreadSleep --stack-depth 5 /tmp/wall.jfr | head -200
   ```
4. Print a ranked list of wall-clock hot spots (methods spending the most real time, including I/O waits).
5. Write results to `.codeflash/jfr-profile.md`.

## Output

Write `.codeflash/jfr-profile.md` with:

```markdown
# JFR Profile Report

- **Type:** CPU / Allocation / Wall-clock
- **Duration:** <N> seconds
- **JDK:** <version from setup.md>
- **Build tool:** <Maven / Gradle>
- **Test command:** <exact command used>

## Top 20 Methods

| Rank | Method | Samples/Bytes | % of Total |
|------|--------|---------------|------------|
| 1 | com.example.Foo.bar() | 1234 | 18.2% |
| 2 | ... | ... | ... |

## Recommended Domain

Based on the profile, the primary bottleneck domain is: **<CPU / Memory / Async / Structure>**

<1-2 sentence justification based on the profile data>
```

If the profile data is empty or the recording failed, report the failure clearly and suggest troubleshooting steps (e.g., check JDK version supports JFR, verify the test command produces activity, ensure sufficient duration).
