Documentation

Learn how to use JVMind to diagnose JVM performance issues

Introduction

JVMind is an AI-powered conversational assistant for Java Virtual Machine (JVM) performance troubleshooting. Upload your GC logs or thread dumps, ask questions in natural language, and get professional diagnostic reports with actionable recommendations.

Instead of manually parsing thousands of log lines or hunting for deadlocks in a massive thread dump, just upload your file and let the AI do the heavy lifting — it will analyze the data step-by-step and explain what's happening in plain English.

Key Features

GC Log Analysis

Upload GC logs and get automatic statistics — throughput, pause times, collector identification, top slowest GC events, and visualized charts.

Thread Dump Analysis

Upload jstack output to detect deadlocks, identify lock contention hotspots, and generate flame graphs of stack traces.

AI-Powered Chat

Ask questions about your analysis results in natural language. The AI uses ReAct reasoning to break down complex problems step-by-step.

Visual Charts

Heap usage curves, pause time distributions, and interactive flame graphs — all generated automatically.

Long-Term Memory

JVMind remembers facts about your environment across conversations, giving you more contextual answers over time.

Flexible LLM Backend

Works with OpenAI, DeepSeek, Qwen, Kimi — or any OpenAI-compatible API.

Main Chat Interface

GC Log Analysis

How to Generate GC Logs

Before uploading, make sure your JVM is configured to output GC logs:

JDK 8-XX:+PrintGCDetails -Xloggc:gc.log
JDK 9+-Xlog:gc*:file=gc.log

How to Analyze

  1. Start a new conversation, or switch to an existing one
  2. Click the Analysis button on the top bar to open the analysis panel
  3. In the GC tab, drag & drop your GC log file, or click to select it
  4. Wait for the analysis to complete — you'll see statistics and charts appear
  5. In the chat, ask the AI to diagnose: "Please analyze this GC log and give me optimization suggestions"
GC Analysis Result

What Gets Analyzed

  • Collector Identification — automatically detects G1, Parallel, Serial, Shenandoah, or ZGC
  • Heap Summary — min, max, and average heap usage
  • GC Statistics — counts by category (Young, Mixed, Full)
  • Throughput — percentage of time the application spends running vs GC pausing
  • Pause Time Analysis — total, average, P95, P99 percentiles
  • Top 10 Slowest — GC events with the longest pauses
  • Full GC by Cause — breakdown of what triggered each Full GC
  • Charts — heap usage timeline, pause time distribution histogram
Tip: For the best AI diagnosis, upload the GC log first, then ask questions in the chat. The AI will automatically reference the already-uploaded analysis data.

Example Questions to Ask

  • "What's the throughput? Is that healthy?"
  • "Why are there so many Full GCs?"
  • "Check if this looks like a memory leak"
  • "What should I adjust to reduce Young GC pause time?"

Diagnostic Rules

JVMind's GC analysis is built on a library of 14 expert rules that detect specific symptoms and assign a severity. Each report is then summarized into a single root cause with two layers of supporting findings: direct evidence and downstream symptoms. This section documents the rules so you know what each detection means and when to take action.

Rules are grouped by which garbage collector they apply to. Universal rules run for every collector. Collector-specific rules only fire when the log is recognized as that collector.

Root Cause Categories

Every report produces exactly one root cause:

CategoryWhat It MeansWhen It's Assigned
oom Heap cannot free space — imminent crash territory. Full GC combined with reclaim < 5%, ZGC allocation stall / cycle failure.
leak Heap trending bad but not yet at OOM. Investigate before it becomes an OOM. Mixed GC unable to keep up with promotion, or Full GC where the heap still has space but cannot allocate contiguous blocks (CMS fragmentation).
performance GC pressure (high pause / frequency / low throughput). Heap still recovers — tune collector config. Any universal perf rule fires, or any CMS/ZGC rule fires without reclaim_low.
healthy No rules fired. All clear. No medium/high findings.

Health Banner Levels

The colored banner at the top of every report is derived from the root cause category and the severity of active findings. The vocabulary is consistent with the diagnosis below — banner never says "critical" while the diagnosis says "performance issue".

Root CauseBanner LevelNotes
oom🔴 Immediate actionAlways critical. Terminal state.
leak + high finding🔴 Immediate actionHeap trending to OOM.
leak + medium finding🟡 AttentionMonitor closely.
performance + any finding🟡 AttentionCapped at warn — perf issues are not imminent crashes.
healthy + raw stats extreme🟡 AttentionSafety net when rules missed something (heap ≥ 98%, > 3 Full GC).
healthy + normal stats🟢 HealthyAll good.

Universal Rules

Apply to every collector. Each rule fires independently based on aggregate statistics.

Rule IDTriggerSeverity ThresholdsOutput
throughput_low Application throughput (1 − pause ratio) below threshold. medium < 95%  |  high < 90% "Application throughput X%, below Y threshold"
stw_time_ratio_high GC pause time consumes a large fraction of the log duration. medium > 5%  |  high > 10% "GC pauses consume X% of log duration"
gc_frequency_high Young GC or Full GC rate above threshold. For Full GC, only counts non-manual triggers — System.gc() / heap dump / heap inspection are excluded (handled by explicit_gc_called instead). Sample-size-aware severity for Full GC: count < 3 → no alert; count 3-4 + rate high → medium; count ≥ 5 + rate high → high. Detail text mentions log duration for short-window context. Young: medium 30/min, high 60/min  |  Full: rate > 0.2/min + count ≥ 3 → medium; count ≥ 5 → high "Full GC X/min, N events, ~Ys apart" + duration context (e.g., "log spans only 25s — small sample, may be transient")
reclaim_low Average reclaim ratio (freed / heap before) of Full or Mixed GC is below threshold. avg_reclaim_ratio < 5% (≤ 2% → high) "Full GC reclaim ratio only X%"
explicit_gc_called Full GC triggered by System.gc() (application code call, not heap pressure). ≥ 1 → medium; ≥ 3 → high "Full GC triggered by System.gc() — consider -XX:+DisableExplicitGC"
single_pause_long Single GC pause exceeds the per-category threshold (Young 200/500ms, Full 1000/3000ms, ZGC 1/5ms, Shenandoah 100/200ms, …). per-category (Young / Mixed / Full / ZGC / Shenandoah / …) "GC#N paused Xms, exceeds Y threshold"

G1-Specific Rules

Fire only when the collector is identified as G1.

Rule IDTriggerSeverity ThresholdsOutput
g1_full_gc G1 should not normally produce Full GC. When it does, it's an exceptional signal. 1-2 → medium; ≥ 3 → high (capped at medium for manual triggers; mixed manual + pressure cases stay high) "G1 had N Full GC(s) …" with extra detail when to-space exhausted / evacuation failure detected. When all triggers are manual, detail explains it. When mixed, detail breaks down manual vs real-pressure counts.
g1_mixed_ineffective Multiple Mixed GC events with persistently rising pre-GC heap. ≥ 3 events, slope > 0.5 MB/event → medium "Heap before Mixed GC keeps rising — incremental reclamation insufficient"
g1_compaction_pause G1 主动全堆压缩 (real heap pressure, G1 cannot reclaim through normal Mixed GC). ≥ 1 → medium; ≥ 3 → high "G1 triggered full heap compaction — Mixed GC cannot keep up with promotion, heap is full"
evacuation_failure (universal) G1 Young/Mixed GC 找不到 Survivor 空间容纳晋升对象 (Old Gen 已满的前兆信号). ≥ 3 → medium; ≥ 10 → high "G1 Young/Mixed GC cannot find Survivor space for promoted objects — a precursor to Full GC"
g1_humongous_allocation 频繁的大对象分配 (G1 humongous object, 易造成老年代碎片化). ≥ 10 → medium; ≥ 30 → high "Frequent large-object allocation — G1 allocates a full region per humongous object, can fragment Old Gen and trigger Full GC"

CMS-Specific Rules

Fire only when the collector is identified as CMS.

Rule IDTriggerSeverity ThresholdsOutput
cms_full_gc CMS Full GC detected — covers JDK9+ unified Garbage Collection (X) and JDK8 classic [Full GC (X)] formats, parsing X as heap inspection initiated gc, heap dump initiated gc, system.gc(), or allocation failure. Breakdown into manual triggers (jmap / jcmd / application code) vs. real heap pressure (Allocation Failure / Promotion Failed). all manual → medium; mixed / real pressure: ≥ 3 → high | otherwise medium "CMS Full GC: 2 manual (inspect) + 3 real (Allocation Failure)"
cms_concurrent_mode_failure Full GC cause contains concurrent mode failure — CMS concurrent cycle could not complete. ≥ 1 → high "CMS concurrent cycle could not complete, heap exhausted"
cms_promotion_failed Full GC cause contains promotion failed — Young Gen objects cannot fit into Old Gen. ≥ 1 → high "Young Gen objects cannot fit into Old Gen"
cms_remark_too_long CMS Remark phase p95 exceeds threshold. medium p95 > 500ms  |  high p95 > 1000ms "Remark phase p95 = Xms, exceeds threshold"
cms_fragmentation Full GC occurs even though post-GC heap is below 70% — fragmented free space blocks contiguous allocations. ≥ 3 events, post-GC avg < 70% → medium "Full GC leaves heap at X% occupied — fragmented free space cannot satisfy allocations"

ZGC-Specific Rules

Fire only when the collector is identified as ZGC.

Rule IDTriggerSeverity ThresholdsOutput
zgc_allocation_stall Allocation request blocked by GC — ZGC enters sync mode. Heap pressure signal alone; pairs with reclaim_low to escalate to OOM via cross-rule logic (matches G1 "Full GC + cannot reclaim" principle). Detection requires a non-zero value in the per-phase Y: Allocation Stalls: X Y Z W line, a non-zero Critical: Allocation Stall stats line, or an event with cause="Allocation Stall" — plain substring matching on the header text would fire false positives when all counts are zero. ≥ 1 (real stall) → high "ZGC sync mode engaged — heap cannot satisfy allocation"
zgc_pause_exceeds_target ZGC p99 pause exceeds its sub-ms design target. medium p99 > 1ms  |  high p99 > 5ms "ZGC pause Xms, exceeds target"
zgc_concurrent_cycle_failure ZGC concurrent cycle failed — typically due to insufficient heap or allocation rate. Heap pressure signal alone; pairs with reclaim_low to escalate to OOM. ≥ 1 → high "ZGC concurrent cycle failed — heap insufficient or allocation rate too high"

Key Design Principles

  • OOM = Full GC + cannot reclaim. A single Full GC with normal reclaim ratio is performance, not OOM. Only when Full GC is combined with reclaim_low (avg reclaim < 5%) does the diagnosis escalate to OOM root cause. This avoids false alarms from System.gc() or one-off heap dumps.
  • Manual triggers are not heap pressure. When the cause is Heap Dump Initiated GC (jmap -dump / jcmd GC.heap_dump) or Heap Inspection (jcmd inspection), the rule fires as intentional, not heap pressure, severity is capped at medium, and the detail text says so explicitly.
  • System.gc() is application code, not heap pressure. Full GC with cause System.gc(), Heap Dump Initiated GC, or Heap Inspection are treated as manual triggers and excluded from gc_frequency_high. Production should consider -XX:+DisableExplicitGC to disable, unless required by libraries (RMI, JMX, etc.). The dedicated explicit_gc_called rule fires at medium (1-2 occurrences) or high (≥ 3) severity with a direct recommendation to investigate the calling code — even when the underlying collector (ZGC, G1, Parallel, ...) is otherwise healthy.
  • G1 mixed-manual detection. When a log has both manual triggers (e.g. System.gc()) and real heap-pressure Full GC (e.g. G1 Compaction Pause), g1_full_gc produces a dedicated "mixed" detail that breaks down both counts separately — so the user understands the diagnosis correctly instead of seeing all Full GC attributed to "heap pressure".
  • CMS rules → performance by default. CMS is designed to allow Full GC fallback. cms_concurrent_mode_failure and cms_promotion_failed alone are categorized as performance; they only escalate to OOM when paired with reclaim_low.
  • ZGC hard fallback → OOM category. ZGC doesn't produce traditional Full GC. Its equivalent hard fallbacks — zgc_allocation_stall (sync mode) and zgc_concurrent_cycle_failure — are categorized as performance by default; they only escalate to OOM when paired with reclaim_low (heap actually cannot reclaim). This matches the same "OOM = cannot reclaim" principle applied to G1, and avoids false-positive OOM alerts when ZGC is operating normally under high allocation rate.
  • Evidence vs Symptoms. Findings are split into two layers based on the active root cause: evidence findings directly support the root cause; symptoms findings are downstream effects. This avoids the confusing flat-list view where unrelated findings mix together.
Tip: Every report has a collapsible Rules Reference panel below the diagnosis listing all 14 rules with thresholds, so you don't need to leave the app to look them up.

Thread Dump Analysis

How to Capture a Thread Dump

Use the jstack command for classic text format (all JDK versions):

jstack -l <pid> > threads.txt

Or use jcmd for the JSON format (JDK 21+, includes virtual thread metadata):

jcmd <pid> Thread.dump_to_file -format=json threads.json

Or capture directly in JVMind using the jstack tab's built-in capture tool (requires the agent to be running on your JVM host).

How to Analyze

  1. Open the analysis panel ( button on the top bar)
  2. Select the jstack tab
  3. Upload your thread dump file
  4. Ask the AI to diagnose: "Find any deadlocks or lock contention in this thread dump"
jstack Analysis Result

What Gets Analyzed

  • Thread State Distribution — counts of RUNNABLE, BLOCKED, WAITING, TIMED_WAITING threads
  • Deadlock Detection — automatically finds circular deadlocks and displays the full wait chain
  • Lock Contention — identifies which locks cause the most blocking
  • Thread Grouping — groups threads by name prefix (e.g., Tomcat worker threads, GC threads)
  • CPU Hotspot Detection — which methods appear most frequently on RUNNABLE threads
  • Flame Graph — interactive flame graph of all stack traces
  • Virtual Threads (JSON only) — count of virtual threads, TERMINATED threads, and thread-container distribution (ForkJoinPool.commonPool, ThreadPerTaskExecutor, …). Unnamed virtual threads are synthesized as VThread-<container>#<tid> for grouping.

Example Questions to Ask

  • "Is there a deadlock? Show me the full chain"
  • "Why is CPU so high? Which threads are running?"
  • "Check for any threads blocked on the same lock"
  • "Help me understand this flame graph — what should I optimize?"

Configuration

LLM Settings

Click the button in the sidebar to open the configuration dialog:

API KeyYour API key for the LLM provider
Base URLAPI endpoint (customize for self-hosted or third-party providers)
ModelWhich model to use (e.g., gpt-4o, deepseek-chat)
TemperatureControls response creativity: lower = more deterministic, higher = more creative
Max IterationsMaximum ReAct reasoning steps the AI can take (higher = more thorough, but slower)
System PromptExtra instructions to guide the AI's behavior

After saving, click "Test Connection" to verify your settings work before starting a conversation.

Configuration Dialog

Supported Providers

JVMind includes presets for popular LLM providers:

  • OpenAI — GPT-4o, GPT-4o-mini
  • DeepSeek — deepseek-chat, deepseek-coder
  • Alibaba Cloud — Qwen (通义千问)
  • Moonshot — Kimi

Conversation Guide

How the AI Thinks

JVMind uses the ReAct (Reasoning + Acting) framework. When you ask a question, the AI:

  1. Thinks about what information it needs
  2. Calls a tool (e.g., analyzes GC log, reads a report, calculates something)
  3. Observes the result
  4. Repeats until it has enough context to give a complete answer

The entire thought process is visible in the conversation — you can see exactly how the AI reached its conclusions.

Tips for Better Answers

  • Be specific — "Check if the Full GC pause time is causing latency issues" is better than "Is GC OK?"
  • Upload first, ask second — upload your GC log or jstack file before asking about it
  • One topic at a time — focus on one issue per message for clearer analysis
  • Use the memory feature — add facts about your application in the sidebar memory panel so the AI remembers them across conversations

Memory

The sidebar Memory panel lets you save facts the AI should remember, such as:

  • Your JVM version and heap size
  • Your application's traffic patterns
  • Previous optimization attempts and their results

The AI automatically references saved facts in future conversations for more contextual answers.

Supported Formats

GC Collectors

JVM VersionGC CollectorSupport
JDK 8Serial, Parallel, CMS, G1
JDK 9+G1
JDK 9+Parallel / Serial
JDK 12+Shenandoah
JDK 11 — JDK 25ZGC (incl. Generational)

Thread Dump Formats

JVMind supports two thread dump formats, auto-detected on upload:

  • Text (jstack -l) — the classic format, works on all JDK versions. Extensions: .txt, .log, .tdump, .jstack.
  • JSON (jcmd Thread.dump_to_file -format=json) — introduced in JDK 21, the only way to see virtual thread details (JEP 444). Extension: .json. Adds statistics for virtual threads, terminated threads, and thread containers (executor / ForkJoinPool grouping).

Files must be UTF-8 encoded (or plain ASCII).

ZGC Specifics

JVMind correctly handles ZGC's multi-phase pause structure by accumulating pause times from all phases of the same GC cycle. It also recognizes both the older Garbage Collection (System.gc()) format and the JDK 25+ Major Collection (System.gc()) format for detecting explicit Full GC triggered by System.gc().

Frequently Asked Questions

Q: Is my data sent to the AI provider?

The analysis results (statistics, not the raw file) are sent to the LLM you configured for diagnosis. The raw file stays on the JVMind server.

Q: Does it work with application servers like Tomcat or Jetty?

Yes — JVMind works with any Java application regardless of the application server or framework. It only needs the GC log or thread dump.

Q: What about very large log files?

File size limits: Loading.... Your current plan's limit is shown in the app sidebar.

Q: How accurate is the AI diagnosis?

The AI provides professional-level analysis comparable to an experienced performance engineer. However, always verify critical recommendations before applying them to production, especially if your log doesn't contain full context.

Q: Can I analyze multiple files at once?

You can upload multiple GC log files or thread dumps to a single conversation. Each will appear in the analysis panel's history, and the AI can compare them.

Q: Does JVMind work with rotating GC logs?

Yes — upload them individually or concatenate them into one file before uploading.

Q: Where can I learn what each diagnostic rule means?

See the Diagnostic Rules section above — it documents all 14 rules, their thresholds, and the root cause categories.