What is Old Generation (Tenured)
The Old Generation (also referred to as Tenured Space) is the region of the JVM Heap dedicated to long-lived objects that have survived multiple collection cycles in the Young G...
🟢 Junior Level
The Old Generation (also referred to as Tenured Space) is the region of the JVM Heap dedicated to long-lived objects that have survived multiple collection cycles in the Young Generation, as well as unusually large objects that bypass Young Gen entirely.
Real-World Analogy
Consider an academic research institution:
- Young Generation (Undergraduate Interns): High volume of seasonal students who stay for a semester and leave. Rapid turnover; simple administrative rosters.
- Old Generation (Tenured Faculty): Professors who have proven their enduring value over years of review cycles. They receive permanent office allocations. Auditing or reorganizing their departments is complex, expensive, and done infrequently.
Ingress Paths: How Objects Enter Old Generation
Objects enter the Old Generation through three distinct mechanisms:
┌────────────────────────────────────────────────────────────────────────┐
│ HOW OBJECTS ENTER OLD GEN │
├────────────────────────────────────────────────────────────────────────┤
│ 1. Aging Promotion: Survived N Minor GCs (Age >= TenuringThreshold) │
│ 2. Premature Promotion: Survivor space overflows during allocation burst│
│ 3. Humongous Allocation: Object size exceeds 50% of G1 region size │
└────────────────────────────────────────────────────────────────────────┘
- Aging Promotion (Standard Path): An object in Eden survives successive Minor GCs, ping-ponging between Survivor spaces until its age reaches
-XX:MaxTenuringThreshold(or the dynamic tenuring ceiling). - Premature Promotion (Survivor Overflow): During high allocation bursts, surviving objects overwhelm the Survivor space (
To-space), forcing the JVM to evacuate remaining survivors directly into the Old Generation. - Direct Humongous Allocation: In G1 GC, large arrays or objects exceeding 50% of a G1 region bypass Eden and Survivor spaces entirely and are allocated directly into contiguous Old Gen regions.
Operational Characteristics
- Typical Size: Typically occupies $\sim 66\%$ (2/3) of total Java Heap memory by default (
-XX:NewRatio=2). - Collection Frequency: Cleaned much less frequently than Young Gen, using Major GC, G1 Mixed GC, or concurrent marking.
🟡 Middle Level
Collection Algorithms: Mark-Sweep vs. Mark-Compact
Because objects in the Old Generation have high survival rates, high-speed Copying algorithms (which require allocating 50% spare buffer space) are economically unfeasible. Instead, collectors apply Mark-Sweep or Mark-Compact:
| Strategy | Operational Mechanism | Advantages | Critical Drawbacks |
|---|---|---|---|
| Mark-Sweep | Marks live objects; leaves surviving objects in place and tracks free slots in Free Lists | Fast reclamation; avoids expensive object relocation | Causes severe memory fragmentation; degrades allocation speed |
| Mark-Compact | Marks live objects, then slides surviving objects contiguously to the start of the heap | Eliminates fragmentation; restores fast bump-the-pointer allocation | Heavy Stop-The-World (STW) pause penalties; must update all moved pointer addresses |
G1 Mixed GC vs. Full GC
In modern JVM deployments using the G1 Garbage Collector, the engine avoids catastrophic monolithic Full GCs through incremental Mixed GCs:
G1 Heap Layout:
[ Young ] [ Young ] [ Old Region 1 ] [ Old Region 2 ] [ Free Region ] ...
│
▼
G1 selects the most fragmented Old Gen regions with the highest garbage yield
("Garbage-First") and collects them incrementally alongside Young Gen regions!
- IHOP (Initiating Heap Occupancy Percent):
When Old Gen occupancy surpasses
-XX:InitiatingHeapOccupancyPercent=45(default 45%), G1 launches background Concurrent Marking. - Adaptive IHOP (
-XX:+G1UseAdaptiveIHOP): In Java 9+, G1 continuously monitors application allocation rates and concurrent marking durations, dynamically adjusting IHOP so that concurrent marking completes just before Old Gen headroom is exhausted. - Mixed GC Execution:
After marking completes, G1 executes a series of Mixed GCs (typically 8 batches,
-XX:G1MixedGCCountTarget=8). Each cycle evacuates all Young regions plus a selected subset of the most garbage-dense Old regions, strictly adhering to the pause target (-XX:MaxGCPauseMillis=200).
The Promotion Failure Catastrophe
Promotion Failure is a severe JVM performance hazard that occurs during a Minor GC:
1. Minor GC starts evacuating surviving objects from Eden/Survivor
│
▼
2. JVM attempts to allocate space in Old Generation
│
▼
3. Old Gen is fragmented or full -> No contiguous memory block fits the object!
│
▼
4. PROMOTION FAILURE! ──> Triggers emergency Stop-The-World Full GC!
When promotion fails, the JVM has no choice but to halt all application threads and execute an emergency Full GC (using the parallel Mark-Sweep-Compact algorithm). This freezes the entire application for hundreds of milliseconds or tens of seconds, causing timeouts and health-check failures.
🔴 Senior Level
Floating Garbage in Concurrent Collectors
In concurrent collectors (G1, ZGC, Shenandoah), background GC threads mark and evacuate Old Generation objects concurrently while application threads (Mutators) continue running:
T0: Concurrent Marking begins (SATB Snapshot taken)
- Object X is marked as LIVE.
T1: Application thread executes: `orderService.currentOrder = null;`
- Object X is now logically DEAD and unreachable!
T2: Concurrent Marking finishes.
- Because Object X was in the T0 snapshot, GC treats it as live!
- Any object that dies after concurrent marking begins is known as Floating Garbage.
- The collector cannot safely reclaim floating garbage during the active cycle; it will be reclaimed during the subsequent collection cycle.
- Architectural Implication: Production heaps must maintain 20–30% free headroom above active data footprints to accommodate floating garbage without triggering allocation stalls.
Concurrent Compaction in Modern Low-Latency Collectors
Legacy collectors require Stop-The-World pauses to slide and compact Old Gen objects because updating object pointers while application threads run risks reading corrupted addresses.
Modern ultra-low latency collectors solve this concurrently:
- ZGC (Colored Pointers & Load Barriers): ZGC relocates Old Generation objects concurrently. If an application thread attempts to access an object while it is being moved, the JIT-compiled Load Barrier intercepts the read, redirects it to the relocated object’s new address, self-heals the pointer in memory, and allows execution to continue without pausing.
- Shenandoah (Load-Reference Barriers): Uses Brooks Forwarding Pointers or modern Load-Reference Barriers (LRBs) to atomically forward thread access from the old memory location to the evacuated copy during concurrent relocation.
Diagnosing Old Gen Failures in Telemetry (-Xlog:gc*)
[GC(45) Pause Young (Normal) (G1 Evacuation Pause) 1800M->1800M(2048M) ... (to-space exhausted)]
[GC(46) Pause Full (Allocation Failure) 1800M->450M(2048M) 2850.120ms]
to-space exhausted: Signals that Survivor and Old Gen regions could not accept promoted objects (Premature Promotion / Sizing failure).Pause Full (Allocation Failure): G1 aborted incremental collection and triggered a 2.85-second STW Full GC compaction freeze.- Remediation: Enlarge heap (
-Xmx), increase G1 region size (-XX:G1HeapRegionSize=16mor32m), or lower IHOP to trigger background marking earlier.
4 Tricky Questions
1. What is Promotion Failure, why is it devastating to application latency, and how do you resolve it?
Answer: Promotion Failure occurs during a Young Generation Minor GC when the collector attempts to promote a surviving object into the Old Generation, but the Old Generation lacks a contiguous memory block large enough to house the object (either due to total heap exhaustion or severe memory fragmentation). When this occurs, the JVM aborts the Minor GC and is forced into an emergency Stop-The-World Full GC on all CPU cores, executing a complete heap compaction. This freezes all application threads for multiple seconds. It is resolved by:
- Increasing overall heap headroom (
-Xmx). - Increasing Survivor space capacity (
-XX:SurvivorRatio) to prevent premature promotion. - Lowering the concurrent marking threshold (
-XX:InitiatingHeapOccupancyPercent) so G1 clears Old Gen regions before they fill up.
2. What is the fundamental difference between a Major GC, a Mixed GC, and a Full GC?
Answer:
- Major GC: Cleans only the Old Generation (historically performed by CMS or Parallel Old).
- Mixed GC (Specific to G1 GC): Cleans the entire Young Generation plus an incrementally selected set of the most fragmented Old Generation regions (“Garbage-First”), keeping pause times predictable and bounded within
-XX:MaxGCPauseMillis. - Full GC: An exhaustive, emergency Stop-The-World collection that cleans and compacts the entire JVM process memory: Young Generation, Old Generation, and Metaspace class metadata. It is the most expensive operation in the JVM lifecycle.
3. What is Floating Garbage in concurrent collectors, and why does it necessitate extra heap headroom?
Answer: Floating Garbage consists of objects that become dead (unreachable) during the concurrent marking phase of a collection cycle. Because concurrent collectors like G1 and ZGC operate based on a snapshot taken at the start of the marking phase (Snapshot-At-The-Beginning / SATB), any object marked as reachable at the beginning of the cycle is preserved through that cycle, even if application threads sever all references to it midway through execution. The collector cannot safely reclaim this memory until the subsequent collection cycle. Because floating garbage temporarily occupies heap space alongside newly allocated objects, production JVMs require a 20–30% memory buffer to avoid running out of allocation headroom before the next cycle runs.
4. How does G1’s Adaptive IHOP work, and why is it superior to hardcoded -XX:InitiatingHeapOccupancyPercent?
Answer: In legacy tuning, IHOP was hardcoded as a fixed static percentage (e.g., -XX:InitiatingHeapOccupancyPercent=45). If traffic spiked suddenly, the application’s allocation rate might fill the remaining 55% of Old Gen before background concurrent marking could finish, causing an emergency Full GC. Conversely, under light traffic, marking started needlessly early, consuming CPU. In modern Java, Adaptive IHOP (-XX:+G1UseAdaptiveIHOP, enabled by default) continuously samples the application’s real-time allocation rate and the duration of recent concurrent marking cycles. It dynamically calculates the exact target threshold to start marking so that the marking phase completes precisely when Old Gen reaches its safe occupancy limit, maximizing throughput while eliminating Full GC risks.
🎯 Interview Cheat Sheet
30-Second Elevator Pitch
“The Old Generation (Tenured) stores long-lived objects that survived aging thresholds in the Young Generation, as well as oversized Humongous objects. Unlike the high-speed copying collector of the Young Gen, Old Gen relies on space-efficient Mark-Sweep-Compact algorithms. In G1 GC, Old Gen is cleaned incrementally via Mixed GCs triggered when occupancy crosses the IHOP threshold (default 45%, managed adaptively). The most critical production risk in Old Gen is Promotion Failure, which occurs when fragmented Old Gen space cannot accommodate promoted objects, triggering an emergency, multi-second Stop-The-World Full GC.”
Key Architectural Takeaways
- Three Ingress Paths: Age threshold reached, Survivor space overflow (Premature Promotion), and Humongous allocations ($>50\%$ G1 region).
- Sizing: Typically $2/3$ of total Heap by default (
-XX:NewRatio=2). - G1 Mixed GC: Collects all Young regions alongside the most fragmented Old regions to avoid monolithic Full GCs.
- Adaptive IHOP: Dynamically predicts when to start background marking based on allocation rates and cycle history.
- Promotion Failure: Occurs when Old Gen cannot fit promoted objects, triggering an emergency Stop-The-World Full GC.
- Floating Garbage: Objects dying mid-cycle survive until the next GC run, necessitating 20–30% heap headroom.
Red Flags & Anti-Patterns
- 🚩 Assuming Old Gen uses the same Copying algorithm as Young Gen: Copying requires 50% empty buffer space, which is impossible in dense Old Gen memory.
- 🚩 Treating Full GC as a normal, acceptable occurrence: Full GCs cause massive STW pauses and violate latency SLAs; they indicate sizing or leak defects.
- 🚩 Hardcoding a high static IHOP (e.g., 75%) without testing: Causes concurrent marking to finish too late, triggering allocation stalls and Full GCs.
- 🚩 Confusing Major GC with Full GC: Major GC targets only Old Gen; Full GC sweeps Young Gen, Old Gen, and Metaspace.
- 🚩 Ignoring
to-space exhaustedwarnings in GC logs: Direct indicator of imminent Promotion Failure.
Related Topics
- What is Young Generation — Eden, Survivors, and promotion source
- What are generations in GC — Generational memory layout overview
- What is G1 GC — Mixed GC, region mechanics, and IHOP tuning
- What is ZGC — Ultra-low latency concurrent Old Gen compaction
- What is stop-the-world — Safepoints and pause-time impact during Full GCs