GC Basics - Minor GC vs Full GC
Minor GC collects only the Young Generation; it is typically frequent and has short pauses. Full GC usually collects the entire heap (Young + Old, and sometimes Metaspace), with longer pauses that should be minimized. This article explains the generational model, Young vs Old, and when Minor and Full GC occur, with examples and a reference table.
Overview
The heap is divided into generations based on the observation that most objects die young:
- Young Generation (Young): New objects are allocated here. Divided into Eden and two Survivor spaces. Young GC (Minor GC) collects this region using a copying algorithm.
- Old Generation (Old / Tenured): Objects that survive several Young GCs are promoted here. Full GC (or Old GC, depending on collector) collects Old and often Young together.
- Metaspace: Stores class metadata. Not part of the Young/Old heap. Can be collected when classes are unloaded; running out of Metaspace can trigger Full GC.
Minor GC: Collects Young only. Eden is full → trigger Minor GC. Live objects are copied between Survivors or promoted to Old. Pause is typically milliseconds. If Old has room for promotions, Minor GC does not touch Old.
Full GC: Collects the whole heap (and possibly Metaspace). Pause can be seconds to tens of seconds. Triggered when Old or Metaspace is full, on explicit System.gc(), or on promotion failure.
Example
Example 1: Minor GC flow (copying)
- Objects are allocated in Eden. When Eden is full, Minor GC runs.
- Live objects in Eden and From-Survivor are copied to To-Survivor (or promoted to Old if they exceed the tenure threshold or Survivor is full).
- Eden and From-Survivor are cleared; From and To swap roles.
- If Survivor cannot hold all live objects, promotion to Old is used. If Old is also full, a Full GC may be triggered.
Example 2: When Full GC is triggered
- Old generation full: Promotions or direct allocation of large objects into Old fail.
- Metaspace full: Too many classes loaded, or Metaspace leak. Set
-XX:MaxMetaspaceSizeto cap growth. - Explicit
System.gc(): Avoid in production; use-XX:+DisableExplicitGCif you do not need it. - Promotion failure: Minor GC cannot promote because Old is full → often leads to Full GC.
Example 3: JVM options (conceptual)
Plain text-Xms2g -Xmx2g -Xmn512m -XX:SurvivorRatio=8
- Heap 2 GB, Young 512 MB (Eden + 2 Survivors). SurvivorRatio=8 → Eden:Survivor:Survivor = 8:1:1. See GC Tuning and G1 Overview for tuning.
Example 4: Comparison
| Type | Scope | Frequency | Pause | Typical trigger |
|---|---|---|---|---|
| Minor GC | Young only | High | Short (ms) | Eden full |
| Full GC | Whole heap (Young + Old, possibly Metaspace) | Low | Long (seconds) | Old/Metaspace full, explicit GC, promotion failure |
Core Mechanism / Behavior
- Young: Usually copying. Eden + 2 Survivors. Objects are copied between Survivors; age increments. After a threshold (e.g. 15) or when Survivor is full, objects are promoted to Old.
- Old: Mark-sweep, mark-compact, or managed by G1/ZGC. Full GC does a full heap scan and reclaim, so it is slow.
- Stop-the-world (STW): GC typically pauses application threads. Minor GC pauses are short; Full GC pauses are long. Low-latency collectors (ZGC, Shenandoah) reduce STW via concurrency.
Key Rules
- Reduce Full GC: Set -Xmx and Young size appropriately. Avoid large objects or long-lived objects filling Old. Check Metaspace and class loading for leaks. Avoid
System.gc()in production. - Observe: Use GC logs (
-Xlog:gc*or-XX:+PrintGCDetails) and monitoring to see Minor/Full frequency and pause times. Investigate with GC Tuning and OutOfMemoryError Playbook when Full GC is frequent or pauses are long. - Generational hypothesis: Most objects die young. Keeping them in Young improves throughput and reduces Full GC pressure.
What's Next
See G1 GC Overview and GC Tuning Principles for collectors and tuning. See OutOfMemoryError Playbook for OOM and heap/Metaspace configuration.