How to Read GC Logs and Spot Memory Issues
Learn how to read gc logs minecraft server outputs, enable GC logging with JVM flags, interpret pause times, and fix memory pressure before it causes lag spikes.
Why GC Logs Matter for Minecraft Servers
Garbage collection (GC) is the JVM process that frees unused memory. Every Minecraft server generates garbage, from chunk data to entity objects to plugin caches, and the GC must clean it up. When the GC cannot keep up, or when it triggers long pauses to reclaim memory, your server stutters. Learning to read gc logs minecraft server produces is the fastest way to diagnose memory-related lag that Spark alone cannot explain. While Spark shows you what is consuming tick time, GC logs reveal whether the JVM itself is struggling underneath.
If you have ever seen your TPS drop to 15 for a fraction of a second every 30 seconds, or noticed lag spikes that correlate with no specific plugin or world event, GC pauses are the most likely cause. The logs tell you exactly when pauses happen, how long they last, and how much memory was reclaimed.
Enabling GC Logging
GC logging is not enabled by default. You need to add JVM flags to your startup script. The flags differ slightly depending on your Java version. For Java 17+ (which you should be running), add these to your startup command:
-Xlog:gc*:file=gc.log:time,uptime,level,tags:filecount=5,filesize=10m
This writes GC events to gc.log in your server directory, rotates across 5 files, and caps each at 10 MB. For Java 11 (not recommended for modern Paper), the equivalent flags use -Xlog:gc with a similar syntax. If you are still on Java 8, use -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps, but seriously consider upgrading.
After adding the flags, restart your server. The gc.log file will start filling immediately. Let it run for at least an hour under normal player load before analyzing. For a deeper look at JVM flags and how they interact with GC behavior, see our JVM flags guide.
Understanding GC Log Entries
A typical G1GC log entry (the default collector for modern Java with Aikar's flags) looks like this:
[2026-05-10T14:22:03.451+0000][12.441s][info][gc] GC(42) Pause Young (Normal) (G1 Evacuation Pause) 4096M->2048M(8192M) 12.345ms
Breaking this down piece by piece:
- GC(42) is the 42nd garbage collection event since startup.
- Pause Young (Normal) means this was a young generation collection, the most common type. Young GC events collect short-lived objects and are usually fast.
- 4096M->2048M(8192M) means heap usage went from 4096 MB to 2048 MB, and the total heap size is 8192 MB. The GC reclaimed roughly 2 GB of garbage.
- 12.345ms is the pause duration. During this time, the server was completely frozen.
Young GC pauses under 20ms are healthy for a Minecraft server. Pauses between 20ms and 50ms are acceptable but worth monitoring. Anything over 50ms will cause noticeable stutter.
Full GC Events, the Red Flag
The entry you never want to see looks like this:
[gc] GC(108) Pause Full (G1 Compaction Pause) 7800M->6200M(8192M) 1842.567ms
A Full GC pause of 1842ms means the server froze for nearly two seconds. Full GC events happen when the young generation cannot free enough memory, forcing the JVM to scan the entire heap. If you see Full GC events in your logs, your server is running out of memory. Common causes include memory leaks in plugins, too many loaded chunks, or simply not enough RAM allocated.
Patterns That Indicate Problems
When you read gc logs minecraft server generates over an hour of gameplay, look for these patterns:
- Increasing heap after GC: If the "after" number in each GC event keeps growing (2048M, then 2200M, then 2400M, then 2600M), memory is leaking. Something is holding references that prevent cleanup. Use Spark's heap dump to identify the leak.
- Frequent young GC: If young GC runs more than once per second, your server is allocating objects at an extreme rate. This often points to a plugin that creates thousands of temporary objects per tick.
- Mixed GC becoming common: G1GC runs "Mixed" collections when the old generation fills up. Occasional mixed collections are normal. Dozens per minute mean objects are surviving too long and filling the old generation.
- To-space exhaustion: Log entries mentioning "To-space exhaustion" mean G1GC ran out of survivor space. This triggers evacuation failures and often leads to Full GC. Increase your heap or tune
-XX:G1ReservePercent.
Tools for Visualizing GC Logs
Reading raw log files is tedious. Several free tools parse GC logs into charts and summaries:
- GCEasy (gceasy.io) accepts a log upload and produces a visual report with pause time distribution, heap usage over time, and specific recommendations. It is the easiest option for a quick overview.
- GCViewer is an open-source desktop application that renders GC logs as interactive graphs. You can zoom into specific time ranges and correlate pauses with in-game events.
- Eclipse MAT is useful when you need to analyze heap dumps alongside GC logs to find the objects consuming memory.
Upload your gc.log to GCEasy after a play session and check the "GC Pause" section. If the 95th percentile pause exceeds 40ms, you have tuning work to do.
Fixing Common GC Issues
Once you can read gc logs minecraft server produces, fixing the issues is usually a matter of adjusting flags or addressing the root cause:
- Long young GC pauses: Reduce
-XX:MaxGCPauseMillis(default 200, try 100 or even 50). G1GC will do smaller, more frequent collections. - Full GC events: Allocate more RAM with
-Xmx, or reduce memory pressure by lowering view distance and simulation distance in paper-world-defaults.yml. - Memory leaks: Identify the offending plugin with Spark heap analysis, then update or replace it. Common leakers include poorly written economy plugins, hologram plugins that do not clean up armor stands, and world editors that cache undo history forever.
- High allocation rate: Check Spark's allocation profiler (
/spark heapdumpand/spark profiler --alloc) to find which plugin is creating the most garbage. Sometimes the fix is as simple as increasing a plugin's update interval from every tick to every 5 ticks.
For a full walkthrough on getting your server to a stable 20 TPS, pair GC log analysis with our 20 TPS optimization guide.
Need a server built for performance? Astroworld Hosting runs NVMe SSDs with optimized Paper configs on every plan.