How G1 GC Works β Regions, Mixed Collections & Humongous Objects
Reviewed by Gurusankar M. Β· Updated Aug 24, 2026
β‘ Short Answer
G1 divides the heap into equal-size regions dynamically tagged Eden/Survivor/Old. It collects the regions with the most garbage first ('garbage first') to meet a pause target. Mixed GCs collect young + some old regions; objects larger than half a region are 'humongous' and handled specially.
βCoffee Chat Question
Concept Made Simple
βHow does G1 GC work internally β regions, mixed collections and humongous objects?β
π§ Mind Map Answer
Remember It Faster
MaxGCPauseMillis is a soft target, not a hard guarantee. G1 tracks how much garbage each region yields per unit of collection time, and before every collection it picks however many regions it estimates it can collect within the pause target β it literally sizes the work to fit the time budget, region by region, rather than committing to a fixed collection set up front. Set the target too low and G1 shrinks the collection set to compensate, which means it reclaims less garbage per pause and has to run pauses more often β 'lower pause target' can paradoxically mean more total time spent pausing, not less.
Humongous objects are costly for two compounding reasons. First, any object bigger than half a region size is allocated directly into a run of contiguous free regions (skipping the normal young-gen allocation path entirely), which can force an otherwise-unnecessary GC just to free up that much contiguous space. Second, those humongous regions live in old gen from birth and are only reclaimed during a full region-emptying collection β they can't be partially collected the way normal old regions can during a mixed GC, so a large array that becomes garbage still sits there, uncollected, until G1 does a collection that happens to fully empty its region.
Tuning G1HeapRegionSize: because the humongous threshold is defined as half a region, the practical fix for frequent humongous allocations is usually raising the region size itself (-XX:G1HeapRegionSize=32m, for example) so the objects triggering it no longer cross that 50% line β not shrinking the objects. Region size must be a power of two between 1MB and 32MB; G1 auto-selects a default based on heap size, but a workload with consistently large allocations (image buffers, large batch payloads) benefits from setting it explicitly rather than relying on the auto-picked default.
Remembered sets are what let G1 collect a handful of young regions without scanning the entire heap for roots. A young-only collection needs to know every old-gen object that references a young object (otherwise a live young object could be missed as garbage), but scanning all of old gen on every minor collection would defeat the purpose of region-based, incremental collection entirely. Instead, each region keeps a remembered set (RSet) β a running list of which other regions point into it β updated incrementally via write barriers every time a reference field is written, using a coarse card table (the heap divided into small fixed-size "cards"; a write marks its card dirty) to keep the bookkeeping cheap. A collection then only needs to scan the RSets of the regions actually being collected, not the whole heap β this is the mechanism that makes G1's pause time roughly proportional to the collection set size, not total heap size, which is exactly what makes a soft MaxGCPauseMillis target achievable on multi-hundred-gigabyte heaps in the first place.
"To-space exhausted" precisely means G1 ran out of empty regions to evacuate live objects into, mid-collection. A G1 collection works by copying every live object out of the regions being reclaimed into fresh, empty regions (the "to-space") β it's a copying collector, not a mark-and-sweep-in-place one. If the heap's free regions run out during that copy (the live set turned out bigger than G1 predicted, often because of a burst of humongous allocations eating into the free-region pool), G1 can't safely stop partway through an evacuation, so it falls back to a full, single-threaded, stop-the-world garbage collection of the entire heap to recover β by far the most expensive pause type G1 can produce, and precisely why the whatIf case above (humongous allocations correlating with to-space exhaustion) is a real production failure mode, not just a log-noise curiosity.
β¨οΈHands-on Keyboard
Learn by Doing
# Set a pause target and a larger region size for a large-allocation workload
java -XX:+UseG1GC -XX:MaxGCPauseMillis=150 -XX:G1HeapRegionSize=32m \
-Xlog:gc*:file=gc.log:time,uptime -jar app.jar
# Grep the log for humongous allocations β the tell-tale sign region size is too small:
grep -i humongous gc.logFewer/no 'humongous' lines once region size comfortably exceeds 2x the large objects' size.
π₯What If?
Think Beyond the Expected
Frequent 'humongous allocation' and to-space exhaustion appear in G1 logs β what's happening?
Large objects (> half a region) allocate directly into contiguous humongous regions, which fragment and pressure Old gen, triggering costly collections. Fix by increasing -XX:G1HeapRegionSize so those objects aren't humongous, or reducing large allocations.
πReal World
G1 is the default and usually fine, but big byte[]/buffers triggering humongous allocations is a known tuning gotcha; bumping region size or avoiding giant arrays resolves the GC pressure.
π―Interviewer's Expectation
Keywords they're listening for:
β οΈCommon Mistakes
- βAllocating huge arrays without considering humongous regions
- βTreating G1 like a generational copying collector
- βSetting an unrealistically low pause target
β Best Practices
- βTune G1HeapRegionSize for large-object workloads
- βSet a realistic pause target and measure
- βWatch for humongous allocations in GC logs
πFollow-up Questions
- 1How does MaxGCPauseMillis influence what G1 collects?
- 2What is a humongous allocation and why is it costly?
- 3When would you tune G1HeapRegionSize?
π§©Related Technologies
πReferences
Continue Learning with AI
Take this question deeper with your favourite AI assistant. Pick a depth, copy the prompt, or open it directly β AI is your learning companion, not a shortcut.
Plain-language foundations
I'm preparing for a software engineering interview and want to understand this from scratch, as a beginner. Topic: Garbage Collection (JVM) Interview question: "How does G1 GC work internally β regions, mixed collections and humongous objects?" Please: 1. Explain the core idea in simple, plain language, using an everyday analogy. 2. Define any technical terms you use. 3. Walk through one small, concrete example. 4. Finish with a single sentence I can easily remember. Keep the tone friendly and assume I'm new to this topic.
Was this answer helpful?
β Featured Products
Support our platform by exploring our recommended products.
As an Amazon affiliate, purchases through these links may earn us a small commission β at no extra cost to you. It helps keep Full Stack Interview Guru free.