MediumπŸ‘€ 3-5 yearsπŸ‘€ 8-15 years 4 min read Updated Aug 24, 2026

Stop-the-World GC Pauses and How to Reduce Them

Reviewed by Gurusankar M. Β· Updated Aug 24, 2026

Asked inAmazonMicrosoftGoogle
#stop-the-world#gc pause#latency#tuning#safepoint
Report issue

⚑ Short Answer

A STW pause halts all application threads (at a safepoint) so GC can work safely. Reduce pauses by lowering allocation rate, sizing generations to avoid full GCs, setting a pause target (G1), or switching to a concurrent collector (ZGC/Shenandoah).

β˜•Coffee Chat Question

Concept Made Simple

β€œWhat is a stop-the-world pause, and how do you reduce GC pause times?”

🧠Mind Map Answer

Remember It Faster

STW→all app threads paused at a safepoint
Reduce→less allocation, right-size gens
G1β†’MaxGCPauseMillis soft target
Eliminate→ZGC/Shenandoah concurrent collectors

A safepoint is a point in a thread's execution where its internal state (register contents, stack layout, object references) is fully known and safe to inspect β€” the JVM can only pause a thread for GC (or run other VM operations, like deoptimization or a thread dump) once every running thread has reached one. Time-to-safepoint is how long the JVM waits for the slowest thread to get there; a thread stuck in a tight loop with no safepoint poll (rare, but possible in JIT-compiled code with no back-edges) or blocked in a long native call can stall the entire STW pause, not just its own work β€” so a GC pause you measure isn't just "the GC's actual work," it also includes however long the slowest thread took to reach a safepoint.

Even a "concurrent" collector (G1, ZGC, Shenandoah) isn't fully concurrent β€” each still has short mandatory STW phases. G1's young/mixed collections are themselves STW (it's concurrent only for the old-gen marking phase); ZGC and Shenandoah do almost everything concurrently but still briefly pause to mark GC roots (thread stacks, static fields) at the very start of a cycle, because roots can change while a thread runs and the set has to be captured atomically. The difference from a fully-STW collector like Parallel GC isn't "zero pauses" β€” it's that the unavoidable pause is O(number of roots), not O(live heap size), so it stays in the single-digit milliseconds even as the heap grows into hundreds of gigabytes.

Allocation rate drives pause frequency directly, not pause length: the young generation is a fixed-size buffer, and every allocation eats into it. A higher allocation rate (more objects created per second) fills that buffer faster, so minor GCs β€” each one a short STW pause β€” fire more often. Cutting allocation (reusing buffers, avoiding unnecessary boxing/autoboxing, streaming instead of materializing full collections) doesn't make an individual pause shorter, it makes pauses less frequent, which is usually what actually improves p99 latency, since most requests just need to avoid landing on a pause rather than needing the pause itself to be faster.

TLABs are why allocation itself doesn't need a lock, even under heavy multi-threaded load. Each thread gets its own small slice of the young generation β€” a Thread-Local Allocation Buffer β€” and a plain-object new is just bumping a pointer within that private slice, no synchronization required, which is what keeps allocation fast enough to sustain a high rate in the first place. A TLAB refill (the thread's slice is full, ask the JVM for a new one) is cheap and doesn't stop other threads. It's minor GC β€” reclaiming the whole young generation, TLABs included β€” that requires the STW pause, because that's the point where live objects need to be identified and copied while nothing else is allowed to mutate references. Tools like GCEasy or GCViewer parse the -Xlog:gc* output from the command above into charts specifically to make allocation-rate-vs-pause-frequency correlations like this visible at a glance instead of hand-counting log lines.

GC ergonomics is why most JVMs never need explicit tuning flags at all β€” on startup, the JVM inspects the machine's available memory and CPU count and auto-selects a default collector (G1 since JDK 9), initial/max heap size, and generation ratios meant to be reasonable for that hardware without any -XX flags. Tuning (a pause target, a region size, an allocation-reduction pass like the ones covered here) is what you reach for once ergonomics' generic defaults demonstrably don't fit a specific workload's latency or throughput requirements β€” not a starting assumption every production JVM needs from day one.

⌨️Hands-on Keyboard

Learn by Doing

bash
# Enable unified GC logging (JDK 9+) to see every STW pause and its cause
java -Xlog:gc*,safepoint:file=gc.log:time,uptime,level,tags -jar app.jar

# Example line from the log β€” this is what you correlate against a p99 spike:
# [12.481s][info][gc] GC(42) Pause Young (Normal) (G1 Evacuation Pause) 512M->128M(1024M) 14.221ms
Output
One line per GC event: cause, heap before/after, and pause duration.

πŸ”₯What If?

Think Beyond the Expected

p99 latency spikes correlate exactly with full GCs β€” what's the fix path?

Full GCs cause long STW pauses. First reduce them: cut allocation/retention, enlarge the heap/young gen to avoid promotion pressure, and ensure you're on G1 with a pause target. If pauses must be sub-ms regardless of heap, move to ZGC.

πŸ˜‚Real World

GC pauses are a top cause of p99 latency spikes and request timeouts. Correlating GC logs with latency graphs is the standard way to prove (and then fix) GC-induced tail latency.

🎯Interviewer's Expectation

Keywords they're listening for:

βœ“ STW = all threads pausedβœ“ safepointβœ“ reduce allocation/promotionβœ“ pause targetβœ“ concurrent GC to eliminate

⚠️Common Mistakes

  • βœ—Treating GC pauses as unavoidable noise
  • βœ—Increasing heap blindly (longer pauses with some collectors)
  • βœ—Not correlating GC logs with latency

βœ…Best Practices

  • βœ“Correlate GC logs with p99 latency
  • βœ“Reduce allocation/retention first
  • βœ“Use concurrent collectors for strict pause SLAs

πŸ”Follow-up Questions

  • 1Why does even a concurrent collector still have short STW phases?
  • 2How does allocation rate drive pause frequency?
  • 3What's a safepoint and time-to-safepoint?

🧩Related Technologies

GC logssafepointsZGCJFR/async-profiler

πŸ“š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: GC Tuning (JVM)
Interview question: "What is a stop-the-world pause, and how do you reduce GC pause times?"

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?

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.

Related Questions