Fundamentals 11 min read

Why Minor, Major, and Full GC Aren’t What You Think – A Deep Dive into JVM GC Pauses

This article clarifies the often‑confusing terminology of Minor, Major, and Full garbage collection in the JVM, explains how each type of GC works, analyzes real GC logs with code examples, and advises monitoring latency or throughput rather than relying on those labels.

Programmer DD
Programmer DD
Programmer DD
Why Minor, Major, and Full GC Aren’t What You Think – A Deep Dive into JVM GC Pauses

When working on GC pause detection at Plumbr, the author found confusion around Minor, Major, and Full GC events and wrote this article to clarify.

The article assumes familiarity with the JVM's basic garbage collection principles. The heap is divided into Eden, Survivor, and Tenured/Old spaces; generational assumptions and other GC algorithms are beyond the scope.

Minor GC

Collecting memory from the young generation (Eden and Survivor) is called Minor GC. Key points:

Triggered when the JVM cannot allocate a new object, e.g., Eden is full; higher allocation rate leads to more frequent Minor GC.

When the memory pool is filled, its contents are copied and the write pointer starts at zero, eliminating fragmentation in Eden and Survivor.

Minor GC does not affect the permanent generation; references from the permanent to the young generation are GC roots, while references from young to permanent are ignored during marking.

Contrary to common belief, not every Minor GC causes a stop‑the‑world pause; pauses are noticeable only when many objects survive and need to be copied.

Thus each Minor GC cleans the young generation memory.

Major GC vs Full GC

These terms lack formal definitions in the JVM specification, but generally:

Major GC cleans the old generation.

Full GC cleans the entire heap, both young and old generations.

In practice, many Major GCs are triggered by Minor GCs, and modern collectors may also clean parts of the permanent generation, making the distinction blurry.

Example GC Log

The following excerpt shows GC events captured 17 seconds after JVM start, revealing 12 Minor GCs and 2 Full GCs over a total pause time of about 50 ms.

java -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC eu.plumbr.demo.GarbageProducer
3.157: [GC (Allocation Failure) 3.157: [ParNew: 272640K->34048K(306688K), 0.0844702 secs] 272640K->69574K(2063104K), 0.0845560 secs] [Times: user=0.23 sys=0.03, real=0.09 secs]

... (additional log lines omitted for brevity) ...

Detailed GC Phases

Using -XX:+PrintGCDetails provides a more granular view:

Initial marking (≈4 ms) stops all application threads.

Parallel marking and cleaning run concurrently with application threads.

Remark phase (≈46 ms) pauses all threads again.

Concurrent sweeping runs in parallel without stopping threads.

The logs show that only a Major GC was performed to clean the old generation, not two Full GCs.

Conclusion

Rather than categorizing GC events as Minor, Major, or Full, monitor application latency or throughput and correlate those metrics with GC pauses. Determine whether a GC pause stopped all threads or ran concurrently, and use that insight for performance tuning.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Garbage CollectionFull GCGC PausesMajor GCMinor GC
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.