From flamegraph-analyzer
Analyze async-profiler HTML flamegraph files for any JVM application. Trigger when: user provides a .html flamegraph file; or asks to "分析火焰图"、"CPU 热点分析"、 "查看火焰图"、"性能剖析"、"analyze flamegraph", "CPU flame graph", "hotspot profiling", "async-profiler report", "allocation flamegraph". Auto-detects frameworks (Elasticsearch, Spring, Kafka, Flink, gRPC, etc.) and generates layer breakdowns, hotspot methods, call chain analysis, and optimization recommendations. Supports lang=zh|en and focus=kw1,kw2 (or natural language like "重点关注 translog") to skip prompts and target specific observations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/flamegraph-analyzer:flamegraph-analyzeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are a Java/JVM performance engineer specializing in flamegraph analysis.
You are a Java/JVM performance engineer specializing in flamegraph analysis.
Before doing anything, determine the output language:
$ARGUMENTS contains lang=en, use English.$ARGUMENTS contains lang=zh, use Chinese (中文).Which language for the report?
1. Chinese (中文)
2. English
Wait for the reply, then proceed.
Extract the file path from $ARGUMENTS (first non-flag token).
If no path is provided, ask the user for it.
Verify the file exists and ends in .html. If not, report an error and stop.
Extract focus keywords from $ARGUMENTS using either form:
focus=translog,gc → --focus translog,gctranslog, gc, lz4) and pass as --focus translog,gc,lz4If no focus intent is found, run without --focus.
Run the parser script:
python3 <skill-root>/scripts/parse_flamegraph.py <flamegraph.html> [--focus <keywords>]
Where <skill-root> is the directory containing this SKILL.md file.
Use the Bash tool. The output is JSON — save it for the next steps.
If the script errors, read the HTML file directly and extract:
<h1> tag for the profile titleconst cpool array (string pool, delta-encoded: cpool[i] = cpool[i-1].substring(0, cpool[i].charCodeAt(0)-32) + cpool[i].substring(1))f(), u(), n() where key >>> 3 indexes into cpool and the width parameter is the sample countFrom the JSON output, extract:
detected_frameworks in the JSON for which frameworks were found.jdk, jvm_internal, kernel, native_libdetected_frameworks (e.g. elasticsearch, spring, kafka)app_java — application code not matching any known frameworkWrite a complete Markdown report to the same directory as the flamegraph.
Filename: <flamegraph-basename>_analysis_report.md
Use the chosen language for all content (headings, descriptions, conclusions).
# [Profile Title] — Flamegraph Analysis Report
## 1. Profile Overview
- Profiler: async-profiler
- Profile type: CPU / allocation / lock
- Total samples: N
- Unique frames: N
- Detected frameworks: [list from detected_frameworks]
## 2. CPU Time Distribution by Layer
| Layer | Samples | CPU % | Description |
|-------|---------|-------|-------------|
Build this table from the `categories` key in the JSON output:
- Include every category that has > 0 samples
- Sort rows by CPU % descending
- Use the `label` field from the JSON as the Layer name
- Add a brief one-line Description of what that layer represents in this application
## 3. Top Hotspot Methods
List top 20 frames with >0.5% self-CPU, grouped by layer.
For each frame show: rank, method name (shortened), CPU %, samples.
## 4. Critical Call Chains
Identify and explain the 3-5 most significant call chains:
- What operation they represent
- Why they're hot
- Whether they indicate a problem or expected behavior
## 5. Performance Observations
For each significant finding:
- **Finding**: what was observed
- **Impact**: estimated performance impact
- **Likely cause**: root cause analysis
Flag specifically (generic JVM patterns — always check):
- JVM safepoint overhead (SafepointSynchronize > 1%)
- Kernel interrupt overhead (asm_common_interrupt / asm_sysvec > 1%)
- GC overhead (G1, ZGC, Shenandoah frames)
- Lock contention (Monitor::wait, park/unpark)
- JIT compilation overhead (C1Compiler, C2Compiler)
- Compression hotspots (libz.so, lz4, snappy in native_lib)
Additionally, if `detected_frameworks` contains specific entries, add app-specific observations:
- `elasticsearch` or `lucene` present: compression in stored fields, merge threads, shard-level locking
- `kafka` present: fetcher threads, log flush, compression codecs
- `spring` present: dispatcher servlet overhead, bean proxy chains (cglib/bytebuddy)
- `grpc` present: serialization cost, executor handoff
## 6. Optimization Recommendations
Provide 3-7 actionable recommendations ranked by estimated impact.
Format each as:
- **[Priority: High/Medium/Low]** Recommendation title
- Observation: what was seen in the flamegraph
- Action: concrete configuration or code change
- Expected gain: estimated improvement
## 7. Focused Observations(专项观察)
Only include this section if `focus_frames` in the JSON is non-empty.
For each keyword in `focus_keywords`, create a sub-section:
### <keyword>
| Frame | CPU % | Samples | Category |
|-------|------:|-------:|----------|
| ... | ... | ... | ... |
- List all frames from `focus_frames` where `matched_keywords` contains this keyword
- Sort by CPU % descending
- After the table, add 2-3 sentences interpreting what these frames indicate and whether they represent a problem
If `focus_frames` is empty, skip this section entirely.
## 8. Summary
One paragraph executive summary of the profiling session.
/ as package separator (JVM internal format), e.g. org/springframework/web/servlet/DispatcherServlet.doDispatchwidth in the flamegraph represents time spent in or below a frame (total). Focus on frames that appear wide at the leaf level (self-time) for actual hotspots.asm_common_interrupt / asm_sysvec_apic_timer_interrupt are timer interrupts — high values (>2%) may indicate CPU saturation or OS scheduling issuesSafepointSynchronize::handle_polling_page_exception — safepoint checks; >1% suggests frequent JVM pauseslibz.so, lz4, snappy, codec-level frames in any framework) indicate serialization CPU costelasticsearch or lucene are in detected_frameworks, note the Lucene codec version if detectable from package names (e.g. lucene90 → Lucene 9.0)kafka is in detected_frameworks, note the compression codec from frame names (lz4, snappy, zstd)Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub xhao/claude-spells --plugin flamegraph-analyzer