# TDA (Thread Dump Analyzer): a Swing GUI and MCP server for Java thread dumps

> TDA reads thread dumps and heap histograms from log files, shows them as a tree, and can also run headless as an MCP server for AI tools. Here is what it does, how to install it, and where its parsing limits bite.

**irockel/tda** — TDA - Thread Dump Analyzer (for Java). Analyze your Thread Dumps with a GUI or use it as MCP Server.

- Repository: https://github.com/irockel/tda
- Website: https://irockel.github.io/tda/
- Stars: 550 · Forks: 97
- Language: Java
- License: LGPL-2.1
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/irockel-tda

## What TDA solves, and who is expected to use it

A Java thread dump is a text snapshot of every thread in a JVM at one instant. On its own it is nearly unreadable: thousands of lines, repeated stack frames, no obvious entry point. TDA exists to turn one or more of those snapshots into something you can navigate. The README describes it as a Swing GUI and MCP Server for analyzing thread dumps and heap information generated by the Java VM, aimed at diagnosing performance issues, deadlocks and memory problems.

The audience is narrow but real. If you are the person paged when a service stops responding and your first move is to run jstack or jcmd against the process, then paste the output into a file, TDA is built for you. It is also aimed at people who keep thread dumps inside larger application logs, where several dumps are interleaved with ordinary log lines. The README lists parsing multiple thread dumps from log files as a core feature, along with a regex you supply to correlate dumps with log timestamps.

Two groups get less out of it. Anyone who never captures dumps has nothing to load. And anyone expecting a live profiler will be disappointed: TDA reads files, it does not attach to a running JVM on its own. The VisualVM and JConsole plugins are the bridge for that workflow, and the README notes the VisualVM Plugin Center build lags at 2.4 while newer releases ship as nbm files.

## How the analysis pipeline works: log files in, tree out

The data flow is file-centric. You point TDA at one or more log files that contain thread dumps. It parses them, detects the individual dumps, and presents them in a tree so you can move between snapshots instead of scrolling. The README calls this the thread dump tree and describes it as the primary navigation surface.

On top of that tree sit the analysis views. Statistical analysis summarizes thread states, monitors, and waiting or locking threads. Long-running thread detection compares consecutive dumps to find threads that have not moved, which is the README's stated way of finding hung or inefficient code. Deadlock detection identifies deadlocks together with the monitor information behind them. Class histogram analysis handles heap objects produced with -XX:+PrintClassHistogram, so the same tool covers a heap-side view without a separate heap dump analyzer.

Virtual Threads are handled as a first-class case, not a footnote. TDA supports Java 1.4.x through Java 21+, and the README calls out analysis of virtual thread states, pinning issues, and carrier thread relationships. Release 3.0 extended the MCP server with carrier thread pinning detection and SMR (Safe Memory Relocation) parsing. If you are debugging a Virtual Threads workload, that carrier-thread relationship is the part that plain text dumps make hardest to see, and it is the strongest reason to pick this tool over a generic text viewer.

For AI-assisted workflows there is a second mode. TDA can run as an MCP Server for headless analysis, and the README names Cursor, Junie and Claude Desktop as integrations. The same parsing engine is exposed without the Swing UI, which is why release 3.0 added logging specifically for troubleshooting in MCP mode.

## Installing TDA and running a first analysis

The simplest path is the self-contained JAR from the Releases page. The README states it runs directly on any system with Java installed. Start it with the command below; the -Xmx512m flag is the value the README uses, and it explicitly says to raise it for several or large log files.

```bash
java -Xmx512m -jar tda.jar
```

Once the window opens, add log files containing thread dumps. TDA parses them and displays the detected dumps in the tree view. If your log lines carry timestamps but the dumps do not, the README says you can supply a regular expression to correlate dumps with log entries; that is the field to fill in before you start comparing snapshots.

On macOS there is a separate route. The DMG bundles its own Java runtime, so no separate Java installation is required. The README describes the DMG as unsigned, which means macOS blocks it on first launch with a developer-cannot-be-verified warning. The documented workaround is to right-click or Control-click TDA.app in Applications and choose Open, then confirm in the dialog; after that first launch it opens normally.

```bash
jcmd <pid> Thread.dump_to_file -format=json <file>
```

The command above is the JSON dump form the README documents. Treat that path as basic: the README states JSON dumps provide name, tid and stack trace but lack details such as thread states and native IDs, and recommends textual dumps for comprehensive analysis. For a first real session, capture a textual dump instead and load that.

## Where TDA is the wrong tool

The JSON limitation is the clearest boundary. Java 21 can write thread dumps as JSON, and TDA can open them, but the README is explicit that the parsed result lacks thread states and native IDs and that textual dumps are recommended for comprehensive analysis. If your pipeline only produces JSON and you need state information, TDA will not give you the analysis you are after. You would have to capture textual dumps as well, which may not be possible after the fact.

Memory is the second constraint. The README frames -Xmx as something you adjust when you have several or big log files, which means large inputs can exhaust the default heap. Parsing a multi-gigabyte production log is not a case the README claims to handle gracefully.

Third, TDA is not a live monitor. It analyzes dumps you already have. If you need continuous JVM telemetry, sampling profiles or allocation tracking over time, a profiler is the right instrument and TDA is not. The VisualVM and JConsole plugins narrow the gap by putting TDA inside a tool that does attach to a JVM, but the analysis itself still works on captured dumps.

Finally, the macOS package is unsigned. That is a distribution decision, not a parsing bug, but it means every first install on a Mac requires the manual right-click and Open step, and managed fleets with strict Gatekeeper policy may refuse the app outright.

## TDA compared with fastThread, an online analyzer

fastThread is the obvious alternative for the same job, and the difference is in where the dump goes. An online analyzer takes an uploaded dump and returns a report, usually with a fixed set of findings: deadlock candidates, thread state distribution, a few heuristics. TDA is a desktop application that parses files on the machine where it runs, with a tree you navigate yourself and filters and categories you define to reduce noise.

That matters for two reasons. Thread dumps routinely contain class names, URLs, credentials in stack frames, and internal hostnames. Keeping them local is a real constraint in regulated environments, and an offline Swing app satisfies it in a way an upload does not. The second reason is repeatability: TDA supports session management, so an analysis can be saved and reopened, and it can compare consecutive dumps to find long-running threads. A one-shot web report is a snapshot; the comparison across dumps is where hung threads become visible.

The trade-off runs the other way too. An online analyzer needs no install and no Java runtime on the analyst's machine, which is useful when you are on a locked-down workstation or want a second opinion quickly. TDA asks you to download a JAR, manage heap with -Xmx, and on macOS work around an unsigned package. If you analyze a dump once a year, that setup cost may not pay off. If you analyze them weekly, the local tree and the saved sessions do.

## Maintenance, releases and the LGPL-2.1 licence

TDA is not archived. The last push to the repository was on 2026-09-06, and releases have been frequent: 3.0 on 2026-01-30, 3.1 on 2026-04-20, and 3.2 on 2026-05-11. The 3.0 release was the large one, bringing the extended MCP server with carrier thread pinning detection and SMR parsing, a FlatLaf-based UI refresh, a dedicated macOS binary, and faster parsing. The 3.1 and 3.2 releases were narrower: VisualVM plugin integration working again, UTF16 logfile parsing, a jsvg update to 2.1.0, and small UI fixes. Renovate is enabled for dependency updates, and the repository includes a Maven build with a CI workflow.

Upgrade cost is low for the standalone JAR: download the new tda.jar and run it. The VisualVM plugin is the awkward case. The README states the last version available in the VisualVM Plugin Center is 2.4, so getting a recent build means downloading three nbm files from the Releases page and installing them manually through the VisualVM plugins settings. If you depend on the plugin path, budget for that manual step on each upgrade.

The licence is LGPL-2.1. For most users that changes nothing: running the JAR, including inside a commercial environment, is not the scenario the copyleft targets. The obligation becomes relevant if you modify TDA and distribute it, or link it into your own distributed work, where the LGPL's relinking and source-availability terms apply. Internal use and unmodified redistribution are the ordinary cases. This is a description of the licence identifier, not legal advice; if you plan to embed TDA in a product you ship, have counsel read the LGPL-2.1 text in the repository's LICENSE file.

## Conclusion

Adopt TDA if you already collect textual thread dumps in log files and want a local, offline viewer that also understands Virtual Threads and can be driven headless through MCP. Do not adopt it if your dumps only exist as Java 21 JSON, because the README states JSON parsing returns name, tid and stack trace but not thread states or native IDs, and that textual dumps are recommended for comprehensive analysis. Before you commit, verify the memory ceiling with a real log file by running java -Xmx512m -jar tda.jar and raising -Xmx if parsing stalls, and check whether the VisualVM Plugin Center build (2.4) or the three nbm files from the Releases page is the version you actually need.

## FAQ

### What tool can I use to analyze thread dumps?

TDA is one option: it parses thread dumps from log files and shows them in a tree, with statistical analysis, deadlock detection and long-running thread comparison. It runs as a standalone Swing application, as a JConsole or VisualVM plugin, or headless as an MCP server.

### How do I install TDA?

Download the self-contained tda.jar from the Releases page and run it with Java installed, or install it as a VisualVM plugin from the Plugin Center, or use the macOS DMG which bundles its own Java runtime. The README notes the Plugin Center build is 2.4 and newer versions require manually installing three nbm files.

### Does TDA support Virtual Threads?

Yes. The README states TDA supports Java 1.4.x through Java 21+ with specialized support for Virtual Threads from Java 19 onward, including virtual thread states, pinning issues and carrier thread relationships. Release 3.0 added carrier thread pinning detection to the MCP server.

### Can TDA analyze JSON-based thread dumps?

It can, but with limits. The README states JSON dumps created with jcmd Thread.dump_to_file -format=json provide basic information such as name, tid and stack trace but lack thread states and native IDs, and recommends textual dumps for comprehensive analysis.

### Is TDA free to use?

TDA is published under LGPL-2.1 and the source is on GitHub. Running the JAR, including in a commercial setting, is the ordinary case; the copyleft terms become relevant if you modify and distribute it or link it into a distributed work.

## Sources

- [irockel/tda on GitHub](https://github.com/irockel/tda)
- [License: LGPL-2.1](https://github.com/irockel/tda/blob/main/LICENSE)
- [Project website](https://irockel.github.io/tda/)
- [README](https://github.com/irockel/tda/blob/main/README.md)
- [Releases](https://github.com/irockel/tda/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/irockel-tda
