GCViewer: reading verbose GC logs from Java 1.6 to unified logging
Fork of tagtraum industries' GCViewer. Tagtraum stopped development in 2008, I aim to improve support for Sun's / Oracle's java 1.6+ garbage collector logs (including G1 collector)
At a glance
- What is it?
- A fork of tagtraum industries' GCViewer that keeps parsing Sun and Oracle garbage collector logs, including G1. It is a desktop analysis tool for engineers who still have to explain a pause distribution, and it has limits worth knowing before you adopt it.
- Who is it for?
- Use GCViewer when you have a GC log from a Sun or Oracle JVM, a 1.8 runtime to run the jar, and a question about pause distribution or heap growth that a chart answers faster than grep. Do not use it as a collector tuner or as a live monitor; it reads files, not running JVMs, and its unified logging parser accepts only the configurations the README lists.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 102 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What GCViewer is for, and who still needs it
A JVM with -Xloggc produces a text file that grows by megabytes per hour. Reading it by hand works for one pause. It stops working when you need the shape of ten thousand pauses across a week, or when someone asks why a service slowed down at 03:00 and the only evidence is a rotated log. GCViewer is a desktop application that turns that file into a chart and a set of summary numbers. The README describes it as "a little tool that visualizes verbose GC output generated by Sun / Oracle, IBM, HP and BEA Java Virtual Machines" and states it is free software under GNU LGPL.
The audience is narrow and specific. You are running a JVM whose collector log format GCViewer recognises, you have the log file on disk, and you want a pause histogram or a heap curve rather than a dashboard. The fork exists because tagtraum industries stopped development in 2008, and the maintainer's stated aim is to improve support for Sun's and Oracle's Java 1.6+ logs, G1 included. Older formats are still listed as supported: Sun JDK 1.2.2 through 1.5, IBM JDK 1.2.2 through 1.3.1, IBM iSeries Classic 1.4.2, HP-UX 1.2 to 1.4.x, and BEA JRockit 1.4.2 to 1.6. That breadth is the reason the project is still useful for archaeology on systems nobody wants to touch.
How the parser turns log lines into chart geometry
The core of the tool is a set of readers, one per log dialect. The README points at DataReaderSun1_6_0.java for the details of which options are honoured, and notes that most of the information a JVM writes is ignored. That is the honest description of the architecture: the parser recognises line shapes, extracts the fields it needs, and discards the rest.
What it extracts drives the first tab. Full GC lines are black verticals, incremental GC lines are cyan. Heap size is a red line, used heap a blue one. Tenured and young generation sizes appear as magenta and orange areas, and the README is explicit that these are not available without PrintGCDetails. For concurrent collectors there is a yellow line marking heap usage at the initial-mark event, plus cyan and pink verticals for the start and end of each concurrent cycle. The second tab lists parsed events grouped by their text, with counts and duration statistics such as median and 75th percentile.
Two definitions in that pipeline are worth understanding because they change what you see. The README states that a pause counts as a full GC pause when the collector prints "full gc" in the event name, or when more than one generation was involved. That second clause is broad. A collection touching young and old together lands in the full GC bucket even if no stop-the-world full collection occurred. Separately, the VM operations area only appears if the log was written with -XX:+PrintGCApplicationStoppedTime, and GCViewer subtracts the GC pause from the reported safepoint pause before showing it, so the number you see is the non-GC part of the stop.
Running GCViewer from the jar: install and first report
There is no installer. The README says you can start the GUI by double-clicking gcviewer-1.3x.jar or by running it, and that it needs a Java 1.8 VM. So the first step is confirming your java command reports 1.8, and the second is having the jar. The README links SourceForge for downloads, and the repository publishes releases; the most recent is 1.37 from 2026-05-25, after 1.36 in 2019 and 1.35 in 2017.
For a batch summary rather than the GUI, the README gives this form, which writes a CSV report and optionally a chart image:
java -jar gcviewer-1.3x.jar gc.log summary.csv [chart.png] [-t PLAIN|CSV|CSV_TS|SIMPLE|SUMMARY]The positional arguments are the log, the output report, and an optional image path. The -t flag selects the report type from the five values shown. If your JVM rotates logs, the README shows that you can pass them all in one argument separated by semicolons:
java -jar gcviewer-1.3x.jar gc.log.0;gc.log.1;gc.log.2;gc.log.current summary.csv [chart.png] [-t PLAIN|CSV|CSV_TS|SIMPLE|SUMMARY]Before any of that, the log has to exist in a format the parser accepts. The README states that best results for non-unified Oracle JDK logging come from this combination:
-Xloggc:<file> -XX:+PrintGCDetails -XX:+PrintGCDateStampsIf you are on OpenJDK 9 or 10 unified logging, the README lists three -Xlog:gc configurations that work, from a defaults form through -Xlog:gc=info:file="path-to-file":tags,uptime,level up to -Xlog:gc*=trace:file="path-to-file":tags,time,uptime,level. It also warns that additional tags are tolerated but ignored, while additional decorations break parsing. That sentence is the most important one in the README for anyone on a modern JDK.
Where the unified logging support stops
Support for -Xlog:gc is described as partial, and the boundary is decoration, not tag. You can add tags; you cannot add decorations. If your logging configuration includes something the parser does not expect in the line prefix, the lines do not match and the chart is empty or short. The failure is silent in the sense that nothing crashes: you get a file with fewer events than the log contains, and the summary is wrong in a way that looks plausible.
That is the main reason to be careful with this tool on a current JVM. The README does not document a validation mode that reports unparsed lines, so the way to check is to compare the event count in the second tab against a line count from the log itself. A second, related limitation is that the tool ignores most of what the JVM writes. If your question depends on a field the parser skips, GCViewer is the wrong tool regardless of how good the chart looks.
There is also the runtime constraint. The README says a Java 1.8 VM is needed to run the jar. Nothing in the README claims support for running GCViewer itself on a later JDK, so treat 1.8 as the requirement it states rather than an assumption you can relax.
GCViewer compared with reading the log directly
The alternative most people reach for first is not another GUI. It is grep, awk and a spreadsheet, or a log pipeline that extracts pause times into a time series database. The difference in approach is real. A grep pipeline gives you exactly the fields you wrote the pattern for, and it scales to logs you never download. GCViewer gives you a fixed set of derived views: the generation areas, the initial-mark line, the concurrent cycle markers, and the pause statistics grouped by event text. You get those without writing a parser, and you get them for log formats you may not have seen before, including the IBM and HP-UX dialects nobody writes new tooling for.
The trade-off is control. A custom extraction handles any decoration, any log version, and any field, because you decide what to match. GCViewer handles the formats its readers know and drops the rest, and the README tells you which options produce the richest output. If your logs are already flowing into a metrics system, adding a second, file-based step is usually the wrong move. If the log is sitting on a filesystem and the question is one-off, the jar is faster than writing the parser.
Maintenance, licensing and what upgrading costs
The last push to the repository was on 2026-06-20, and release 1.37 is dated 2026-05-25. Before that, 1.36 was released in 2019 and 1.35 in 2017. That cadence matters more than any single release: this is a project that moves when someone needs it to move, with long quiet stretches in between. If you adopt it, plan for the possibility that a log format change on your side is not fixed upstream quickly.
The licence situation is worth reading carefully. The README states the project is released under GNU LGPL, while the repository metadata carries a NOASSERTION licence identifier and the top level contains LICENSE.txt. Those two signals do not agree, so the file is the thing to read rather than the badge. LGPL matters if you intend to link against or modify the source and distribute the result; it matters much less if you download the jar and run it. That is a description of the licence family, not advice about your situation.
Upgrade cost is low in the ordinary case. The artifact is a self-contained jar, the CLI contract shown in the README has been stable across releases, and the report type values are the same. The cost that is not low is environment drift: if the JVM producing your logs moves to a newer unified logging configuration with extra decorations, GCViewer will not follow it for you.
Editorial conclusion
Use GCViewer when you have a GC log from a Sun or Oracle JVM, a 1.8 runtime to run the jar, and a question about pause distribution or heap growth that a chart answers faster than grep. Do not use it as a collector tuner or as a live monitor; it reads files, not running JVMs, and its unified logging parser accepts only the configurations the README lists. Before you commit, verify three things: that your log was written with -Xloggc:<file> -XX:+PrintGCDetails -XX:+PrintGCDateStamps or one of the listed -Xlog:gc forms, that the pause numbers you care about appear under the Full gc pauses or Gc pauses columns rather than being folded into a different bucket, and that the LGPL terms in LICENSE.txt fit how you intend to distribute anything built on the source.
Frequently asked questions
how to use gcviewer
Run the jar directly, either by double-clicking gcviewer-1.3x.jar or with java -jar gcviewer-1.3x.jar for the GUI. For a batch report, pass the log, an output CSV and an optional chart image, for example java -jar gcviewer-1.3x.jar gc.log summary.csv chart.png. The README notes a Java 1.8 VM is required to run it.
Which GC log format should I generate for GCViewer?
For non-unified Oracle JDK logs the README says best results come from -Xloggc:<file> -XX:+PrintGCDetails -XX:+PrintGCDateStamps. On OpenJDK 9 or 10 unified logging, three -Xlog:gc configurations are listed as working, from the defaults form up to -Xlog:gc*=trace:file="path-to-file":tags,time,uptime,level. Additional tags are ignored, but additional decorations break parsing.
Why does GCViewer show no tenured or young generation data?
The README states that the tenured generation and young generation areas are not available without PrintGCDetails. Without that option the parser has no generation sizes to plot, so those parts of the chart stay empty while the heap and used heap lines still appear.
Can GCViewer read rotated GC logs?
Yes. The README shows that when logfile rotation with -XX:+UseGCLogFileRotation is enabled, the files can be passed at once as a single semicolon-separated argument, for example gc.log.0;gc.log.1;gc.log.2;gc.log.current.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/chewiebug-gcviewer)