This guide walks you through profiling a Java application and analyzing the results with ap-query.
Prerequisites
Profile your application
Use asprof to collect a profile. The most common profiling scenarios:
CPU profiling
Wall-clock profiling
Allocation profiling
Profile CPU usage for 30 seconds:asprof -d 30 -o jfr -f profile.jfr <pid>
CPU profiling shows where your application spends time executing code. Profile wall-clock time including I/O and locks:asprof -d 30 -e wall -o jfr -f profile.jfr <pid>
Wall-clock profiling includes threads waiting on I/O, locks, or sleeping. Profile memory allocations:asprof -d 30 -e alloc -o jfr -f profile.jfr <pid>
Shows which methods allocate the most memory.
Replace <pid> with your Java process ID. Find it with jps or ps aux | grep java.
Analyze with ap-query
Start with triage
The info command gives a comprehensive overview:
ap-query info profile.jfr
Profile: profile.jfr
Duration: 30.0s
Event: cpu (12,450 samples)
Total: 12,450 samples
Top 20 hot methods (self time):
12.3% 1,532 sun.nio.ch.EPollArrayWrapper.poll
8.7% 1,083 java.util.HashMap.resize
6.2% 772 com.example.Parser.parseToken
4.8% 598 java.lang.String.split
...
Thread distribution:
45.2% 5,627 http-nio-8080-exec-
32.1% 3,997 kafka-consumer-thread-
12.8% 1,594 scheduling-thread-
9.9% 1,232 background-worker-
Find hot methods
Rank methods by self and total time:
ap-query hot profile.jfr --top 20
Output shows methods sorted by self time (time spent in the method itself) and total time (including callees).
Drill into a method
See what a hot method calls:
ap-query tree profile.jfr -m HashMap.resize --depth 6
HashMap.resize (1,083 samples, 8.7%)
├─ HashMap.putVal (892 samples, 7.2%)
│ ├─ HashMap.put (892 samples, 7.2%)
│ │ ├─ CacheManager.store (445 samples, 3.6%)
│ │ │ └─ RequestHandler.process (445 samples, 3.6%)
│ │ └─ UserService.addUser (447 samples, 3.6%)
│ │ └─ UserController.createUser (447 samples, 3.6%)
└─ [other callers] (191 samples, 1.5%)
Find the hottest path
Trace from a method to the leaf:
ap-query trace profile.jfr -m HashMap.resize
Shows the single most expensive path through your code.
See who calls a method
Find caller paths:
ap-query callers profile.jfr -m HashMap.resize
Inverted call tree showing which methods call into HashMap.resize.
Analyze over time
View sample distribution across time:
ap-query timeline profile.jfr
Timeline (30.0s, 15 buckets)
0.0s-2.0s 423 ████████████░░░░░░░░ HashMap.resize (12%)
2.0s-4.0s 512 ███████████████░░░░░ Parser.parseToken (15%)
4.0s-6.0s 398 ████████████░░░░░░░░ String.split (9%)
6.0s-8.0s 445 █████████████░░░░░░░ EPoll.poll (8%)
...
28.0s-30.0s 387 ███████████░░░░░░░░░ HashMap.resize (11%)
Common workflows
Compare before and after
Profile before and after an optimization:
# Profile before
asprof -d 30 -o jfr -f before.jfr <pid>
# Make your optimization
# ...
# Profile after
asprof -d 30 -o jfr -f after.jfr <pid>
# Compare
ap-query diff before.jfr after.jfr --min-delta 0.5
The diff output shows REGRESSION (slower), IMPROVEMENT (faster), NEW, and GONE methods.
Analyze a time window
Focus on a specific time range:
# First, see the timeline
ap-query timeline profile.jfr
# Then zoom into a spike at 12-14 seconds
ap-query hot profile.jfr --from 12s --to 14s
Filter by thread
Analyze a specific thread pool:
# See thread distribution
ap-query threads profile.jfr
# Focus on HTTP threads
ap-query hot profile.jfr -t "http-nio"
Remove idle samples
For wall-clock profiles, filter out idle waiting:
ap-query hot profile.jfr --event wall --no-idle
The --no-idle flag removes samples where threads are blocked on I/O, sleep, or park operations.
Agent-driven workflow
If you installed the agent skill (installation guide), you can ask your coding agent to handle all of this:
Profile this application with async-profiler and analyze the result.
Start with hotspot triage, then drill down and report concrete next actions.
The agent will:
- Profile your application with
asprof
- Run
ap-query info for triage
- Drill into hot methods with
tree, trace, and callers
- Provide specific optimization recommendations
Next steps
Command reference
Explore all commands and flags
Profiling workflow
Learn the complete analysis workflow
Event types
Understand CPU, wall, alloc, and lock events
Scripting
Write custom analysis scripts