[![Java CI with Maven](https://github.com/irockel/tda/actions/workflows/build.yml/badge.svg)](https://github.com/irockel/tda/actions/workflows/build.yml) [![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://github.com/irockel/tda/issues?q=is%3Aissue+is%3Aopen+label%3Adependencies) [![Dependencies](https://img.shields.io/librariesio/github/irockel/tda)](https://libraries.io/github/irockel/tda) [![License](https://img.shields.io/github/license/irockel/tda)](LICENSE) # TDA - Thread Dump Analyzer > [!IMPORTANT] > > **2026-05-11 - TDA 3.2 available.** > * **VisualVM Plugin**: proper integration in VisualVM working again. > * **UI**: Updated jsvg version to 2.1.0. > > **2026-04-18 - TDA 3.1 available.** > * **VisualVM Plugin**: proper integration in VisualVM working again. > * **Logfile Parsing**: Support for UTF16 files. > * **UI**: some small fixes. > > **2026-01-30 - TDA 3.0 is now available!** 🚀 > This major release brings significant enhancements: > * **Extended MCP Server**: Now with **Carrier Thread Pinning** detection and support for **SMR (Safe Memory Relocation)** parsing. > * **Modernized UI**: Completely refreshed look and feel using **FlatLaf**. > * **Usability Improvements**: Fixed several long-standing issues, including improved split-pane management and faster parsing. > * **Native macOS Support**: Now providing a dedicated macOS binary. > * **Logging**: Especially for troubleshooting in MCP Mode. TDA (Thread Dump Analyzer) for Java is a powerful yet lightweight Swing GUI and **MCP Server** for analyzing Thread Dumps and Heap Information generated by the Java VM. It is designed to assist in diagnosing performance issues, deadlocks, and memory problems in Java applications. With its MCP capabilities, TDA can be seamlessly integrated into AI-powered development workflows. TDA supports Java 1.4.x through Java 21+, including specialized support for **Virtual Threads** (Java 19+) and **JSON-based thread dumps** (Java 21+, experimental). ## 📋 Table of Contents - [🚀 Key Features](#-key-features) - [📦 Installation](#-installation) - [1. Self-contained JAR](#1-self-contained-jar) - [2. VisualVM Plugin](#2-visualvm-plugin) - [3. macOS Binary (DMG)](#3-macos-binary-dmg) - [🛠 Usage Modes](#-usage-modes) - [1. Standalone Application](#1-standalone-application) - [2. JConsole Plugin](#2-jconsole-plugin) - [3. VisualVM Plugin](#3-visualvm-plugin-1) - [4. JSON-based Thread Dumps (Experimental)](#4-json-based-thread-dumps-experimental) - [5. MCP Server (Headless Analysis)](#5-mcp-server-headless-analysis) - [6. Agent Skill (Multi-Agent Support)](#6-agent-skill-multi-agent-support) - [🏗 Building from Source](#-building-from-source) - [🛠️ Troubleshooting](#-troubleshooting) - [📜 Changelog](CHANGELOG.md) - [📜 License](LICENSE) ## 🚀 Key Features * **Comprehensive Thread Dump Parsing**: Parse multiple thread dumps from log files and display them in an intuitive tree structure. * **Virtual Threads Support**: Analyze virtual thread states, pinning issues, and carrier thread relationships. * **Statistical Analysis**: Detailed statistics about thread states, monitors, and waiting/locking threads. * **Long-Running Thread Detection**: Identify threads that persist across multiple dumps, helping find "hung" or inefficient code. * **Deadlock Detection**: Automatic identification of deadlocks with detailed monitor information. * **JSON-based Thread Dumps**: Support for parsing JSON-formatted thread dumps created with `jcmd Thread.dump_to_file -format=json `. *Note: JSON dumps currently provide basic information (name, tid, stack trace) but lack details like thread states or native IDs. For comprehensive analysis, textual dumps are recommended.* * **Class Histogram Analysis**: Integrated analysis of heap objects (via `-XX:+PrintClassHistogram`). * **Flexible Filtering & Categorization**: Use custom filters and categories to manage large numbers of threads. * **AI Agent & MCP Support**: Headless analysis mode and standardized Agent Skill for integration with AI tools like Junie, Claude Code, OpenCode, Codex, and Pi. * **Session Management**: Save and reopen analysis sessions. --- ## 📦 Installation TDA can be installed or used in several ways: ### 1. Self-contained JAR The simplest way to use TDA is to download the `tda.jar` from the **Releases** page. Since it's a self-contained JAR, you can run it directly on any system with Java installed. ### 2. VisualVM Plugin TDA is available as a plugin for VisualVM. You can install it directly from the **VisualVM Plugin Center** (Tools -> Plugins). This integrates TDA's analysis capabilities directly into your VisualVM environment. The last available version in the plugin center is 2.4. For installing the recent version, download the three nbm files from the Releases page and install them manually in the VisualVM plugins settings. ### 3. macOS Binary (DMG) TDA provides a native macOS DMG package for easier installation. This package includes its own Java runtime, so no separate Java installation is required to run it. #### Installation (Unsigned Binary) Since the DMG is currently unsigned, macOS will block it by default with a warning that the "developer cannot be verified". To install and run TDA: 1. Download the `TDA-.dmg` from the Releases page. 2. Open the DMG and drag **TDA.app** to your **Applications** folder. 3. **Right-click** (or Control-click) on `TDA.app` in your Applications folder and select **Open**. 4. A dialog will appear asking if you are sure you want to open it. Click **Open**. 5. After this first launch, you can open TDA normally from Launchpad or Spotlight. If this fails, you might need to confirm the installation from the system settings. For this just follow the instructions after clicking on the '?' Icon on the upper right corner of the error dialog. --- ## 🛠 Usage Modes TDA can be used in five different ways to suit your environment: ### 1. Standalone Application The most common way to use TDA for offline analysis of production log files. (See **[Installation](#1-self-contained-jar)** for how to get the JAR). **How to run:** ```bash java -Xmx512m -jar tda.jar ``` Once opened, you can add log files containing thread dumps. TDA will parse them and display them in the tree view. If you have several or big log files, you might need to adjust the memory allocation by increasing the `-Xmx` flag.
TDA Main Screen
#### Important Features: * **Thread Dump Tree**: Navigate through all detected dumps in a log file. * **Regular Expression for Timestamps**: Since thread dumps often lack timestamps, you can provide a regex to correlate dumps with log entries. * **Find Long Running Threads**: Compare consecutive dumps to see which threads haven't moved. * **Filters & Categories**: Group threads by name or state to reduce noise. * **Monitors & Deadlocks**: Detailed view of monitor usage and automatic deadlock detection. ### 2. JConsole Plugin Analyze a running application directly within JConsole. This is particularly useful for production environments where you need to quickly inspect the state of a live system. The plugin is part of the standalone jar, which needs to be downloaded for this. **How to use:** Start JConsole with the TDA plugin: ```bash jconsole -pluginpath tda.jar ``` A new "Thread Dumps" tab will appear. From here, you can: * **Request Thread Dumps**: Generate fresh dumps directly from the connected JVM. * **Analyze in Real-time**: Use all of TDA's parsing and analysis features on the live data. ### 3. VisualVM Plugin TDA is also available as a plugin for VisualVM. You can install it directly from the **VisualVM Plugin Center**. It provides the same powerful analysis tools integrated into your VisualVM workflow. (See **[Installation](#2-visualvm-plugin)** for details). ### 4. JSON-based Thread Dumps (Experimental) Newer JDK versions allow generating thread dumps in JSON format using: ```bash jcmd Thread.dump_to_file -format=json ``` TDA can parse these files, but please note that the information provided in the JSON format is currently more basic than the traditional textual output. For example, it often lacks detailed thread states (like `MONITOR_WAIT` vs `WAITING`) or native thread IDs (`nid`). **Recommendation:** For in-depth analysis of deadlocks, monitor contention, or specific thread states, the **textual thread dump format is still preferred**. ### 5. AI Agent & MCP Integration (Headless Analysis) For integration with AI assistants (such as Junie, Claude Code, OpenCode, Codex, and Pi Agent) or automated pipelines, TDA can run headlessly via the **Model Context Protocol (MCP)** or as a standardized **Agent Skill**. This offloads computation and parsing to TDA, preventing agents from consuming token budgets and degrading context by ingesting raw multi-megabyte log files. There are two primary ways to integrate TDA into your AI workflow: #### Option 1: Agent Skill Configuration (Recommended) TDA provides a standardized **Agent Skill** (`tda-thread-dump-analysis`) conforming to the open [agentskills.io](https://agentskills.io) specification. ##### ✨ Benefits - **🛑 Strict Context Guardrails**: Instructs agents never to `cat` or read massive raw log files into context. - **📋 Structured Diagnostic Protocol**: Automatically sequences the investigation: `parse_log` ➔ `get_summary` ➔ `check_deadlocks` ➔ `analyze_virtual_threads` ➔ `find_long_running` ➔ `drill_down`. - **🔄 Dual-Mode Compatibility**: Supports agents with native MCP (Junie, Claude Code, OpenCode, Codex) as well as minimal/bash-centric agents like **Pi Agent** via a bundled CLI bridge (`scripts/tda_client.py`). ##### Skill Installation & Discovery - **Via Agent Skills Package Manager**: ```bash npx skills add https://github.com/irockel/tda ``` - **Via Repository Symlink**: The skill is located canonically in `.agents/skills/tda-thread-dump-analysis/` and exposed via `skills/tda-thread-dump-analysis/`: - **Junie**: `.junie/skills/` or `.agents/skills/` - **OpenCode**: `.agents/skills/` or `.opencode/skills/` - **Claude Code**: `.claude/skills/` or `.agents/skills/` - **Codex**: `.agents/skills/` - **Herdr**: Shared workspace `.agents/skills/` ##### Standalone CLI Bridge for Pi Agent & Terminal Agents For agents without native MCP support (such as **Pi Agent** or CLI subagents): ```bash # Full end-to-end automated analysis report: python3 .agents/skills/tda-thread-dump-analysis/scripts/tda_client.py analyze /path/to/dump.log # Structured JSON output for agents: python3 .agents/skills/tda-thread-dump-analysis/scripts/tda_client.py analyze /path/to/dump.log --json # Specific diagnostic queries: python3 .agents/skills/tda-thread-dump-analysis/scripts/tda_client.py deadlocks /path/to/dump.log python3 .agents/skills/tda-thread-dump-analysis/scripts/tda_client.py virtual-threads /path/to/dump.log python3 .agents/skills/tda-thread-dump-analysis/scripts/tda_client.py long-running /path/to/dump.log ``` --- #### Option 2: Direct MCP Server Integration If you prefer to configure TDA directly as a native MCP server in your agent or MCP client (e.g. Junie, Claude Desktop): ##### How to Run: ```bash java -Djava.awt.headless=true -jar tda.jar --mcp ``` ##### Integration Example (e.g. Junie `mcp.json` or standard MCP client): ```json { "mcpServers": { "tda": { "command": "java", "args": ["-Djava.awt.headless=true", "-jar", "path/to/tda.jar", "--mcp"] } } } ``` ##### Recommended System Prompt (Direct MCP Mode) When using direct MCP without the skill package, configure a system prompt (e.g. in `~/.junie/instructions.md` or your agent's system prompt) to prevent agents from dumping large files into context: ```markdown When you encounter a log file that appears to contain Java thread dumps: 1. DO NOT try to read or "cat" the entire file if it's large. 2. Use the `tda` MCP toolset. 3. First, call `parse_log(path="...")` to initialize the analysis. 4. Use `get_summary()`, `check_deadlocks()`, `find_long_running()`, `analyze_virtual_threads()`, `get_native_threads()`, and `get_zombie_threads()` to perform the analysis. 5. Provide your insights based on the structured data returned by these tools rather than the raw log text. ``` --- #### Available MCP Tools The MCP server exposes the following tools (available both via direct MCP calls and via the CLI bridge): | Tool | Arguments | Description | |:--------------------|:--------------------------|:-----------------------------------------------------------------------------------------------| | `parse_log` | `path` (string, required) | Parses a log file containing Java thread dumps. This must be the first action for a log file. | | `get_summary` | None | Returns a summary of all parsed thread dumps (index, name, timestamp, thread/deadlock counts). | | `check_deadlocks` | None | Checks for and returns information about any deadlocks detected in the parsed thread dumps. | | `find_long_running` | None | Identifies threads that remain in the same state/stack trace across consecutive dumps. | | `analyze_virtual_threads` | None | Detects virtual threads where the carrier thread is stuck in application code. | | `get_native_threads` | `dump_index` (int, required) | Returns a list of all threads in a native method for a specific thread dump. | | `get_zombie_threads` | None | Returns a list of zombie threads (unresolved SMR addresses) with timestamps and dump names. | | `clear` | None | Resets the server state and clears the internal thread store for a new log file. | There is also an [article on dev.to](https://dev.to/irockel/stop-reading-raw-stacktraces-ai-powered-java-thread-dump-analysis-with-mcp-4673) about how to use TDA as an MCP server. 👉 **For complete configuration recipes across Junie, OpenCode, Claude Code, Codex, Pi, and Herdr, see the [Multi-Agent Integration Guide](docs/agent-integration.md).** 👉 **For JVM thread states, monitor locking graphs, and virtual thread pinning theory, see the [Diagnostics Reference Guide](.agents/skills/tda-thread-dump-analysis/references/diagnostics.md).** --- ## 🏗 Building from Source TDA is built using Maven. It requires **Java 11** or higher to build and run. ```bash mvn clean package ``` This will build all components: * The standalone TDA JAR (in `tda/target/tda-x.x.jar`). * The VisualVM plugins as NBM files (in the `target/` directory of each `visualvm-*` module). To build the macOS DMG package, use the `release` profile (requires macOS and JDK 17+): ```bash mvn clean package -Prelease ``` The resulting standalone JAR will also be located in the `tda/target/` directory. --- ## 🛠️ Troubleshooting If you encounter issues while using TDA, check the following sections for guidance. ### 1. Logging TDA maintains a centralized log file to help diagnose issues. If something isn't working as expected, the log file is the first place to look. #### Log File Locations * **macOS**: `~/Library/Logs/TDA/tda.log` * **Windows**: `%LOCALAPPDATA%\TDA\Logs\tda.log` * **Linux/Unix**: `~/.tda/logs/tda.log` #### Error Indicators (UI Mode) In standalone or plugin mode, TDA will display a **red dot** in the status bar (next to the memory indicator) if a critical error has occurred. Hover over the dot to see a tooltip reminding you to check the log file. ### 2. MCP Server Specifics Running TDA as a headless MCP server has specific requirements: * **Headless Environment**: Ensure you pass `-Djava.awt.headless=true` when running the JAR. TDA is a Swing-based application, and the MCP mode must bypass UI initialization. * **Std-in/Std-out Pollution**: The MCP protocol communicates via `stdin` and `stdout`. Avoid using any commands or scripts that print additional information to `stdout`, as this will corrupt the JSON-RPC stream and cause the AI client to lose connection. * **Absolute Paths**: When calling `parse_log`, always use **absolute paths** for the log file. The working directory of the MCP server might not be what you expect depending on how your AI client (e.g., Claude Desktop) launches it. * **Permissions**: Ensure the user running the AI client has read permissions for the log files being analyzed. ### 3. Memory Management Thread dumps from large production systems can be hundreds of megabytes. * **OutOfMemoryErrors**: If TDA crashes or fails to parse a large file, increase the heap size using the `-Xmx` flag: ```bash java -Xmx2g -jar tda.jar ``` * **Max Logfile Size**: TDA has a safety limit for log file sizes. You can adjust this in the **Preferences** dialog (UI mode) or by manually editing the configuration if necessary. --- ## 📜 License TDA is licensed under the **Lesser GNU General Public License (LGPL)**. --- *For more detailed information, please refer to the source code. The wiki has been removed because it was outdated.*