Safepoints and Stop-The-World Pauses
Some JVM jobs, such as parts of garbage collection, can only be done safely when no Java thread is changing the heap. The JVM then brings every application thread to a safepoint: a point in the code where the thread's state is known, so its references can be found and objects can be moved. While threads are held at the safepoint, the application is stopped; this is a stop-the-world (STW) pause. In this lesson, you will learn why safepoints exist, what triggers them, how to see them in logs, and what makes them long.
How a Safepoint Works
- The JVM requests a safepoint.
- Each running thread stops at its next safepoint check: at method returns, loop back-edges and certain calls. Threads already blocked or in native code count as stopped.
- When all threads have stopped, the JVM does its work.
- All threads resume.
What Triggers Safepoints
| Trigger | Example |
|---|---|
| Garbage collection phases | Young collections, remark, cleanup, full GC |
| Deoptimization | Throwing away compiled code that is no longer valid |
| Thread dumps and some diagnostics | jstack, Thread.getAllStackTraces() |
| Class redefinition | Debuggers, some agents |
| Biased-locking revocation (older JVMs) | Removed in modern Java |
Seeing Safepoints in the Log
The JVM can log every safepoint with -Xlog:safepoint. Here is a real excerpt from a small program that called System.gc() on JDK 25 with G1 (some fields in the middle of each line are replaced with "..." to fit the page):
[0.012s][info][safepoint] Safepoint "G1TryInitiateConcMark", ..., Reaching safepoint: 1041 ns, At safepoint: 235917 ns, ..., Total: 237833 ns, Threads: 0 runnable, 10 total
[0.013s][info][safepoint] Safepoint "G1CollectFull", ..., Reaching safepoint: 6333 ns, At safepoint: 923250 ns, ..., Total: 930917 ns, Threads: 0 runnable, 10 totalExplanation: Each line names the operation that needed the safepoint ("G1CollectFull" is the full collection that System.gc() requested). Reaching safepoint is how long the JVM waited for all threads to stop (about 6 microseconds), and At safepoint is how long the work took while they were stopped (about 0.9 milliseconds). Their sum is the pause the application felt.
What Makes Pauses Long
- Lots of live data to copy or mark during a stop-the-world GC phase.
- Slow time-to-safepoint: a thread in a long loop that the JIT compiled without safepoint checks (modern JVMs add checks to most loops), or a huge array copy.
- Too-small heaps, which cause frequent or full collections.
- Many threads, each of which must stop.
Common Mistakes
Blaming all pauses on garbage collection. Thread dumps, deoptimization and other operations also use safepoints.
Only looking at GC time. Time to reach the safepoint adds to the pause too.
Interview Corner
What is a safepoint in the JVM?
A safepoint is a point in execution where a thread's state, especially the location of all object references, is well defined, so the JVM can safely inspect or modify the heap and thread stacks. For operations such as many GC phases, deoptimization or thread dumps, the JVM requests a global safepoint and waits for all Java threads to reach one; they stay stopped while the operation runs, which is a stop-the-world pause. Pause length is the time to reach the safepoint plus the time spent at it, and both can be logged with -Xlog:safepoint.
Practice
- Easy: Run any program with
-Xlog:safepointand find the operation names that appear. - Harder: Call
Thread.getAllStackTraces()in a loop 100 times while logging safepoints, and count the safepoints it causes.
Key Takeaways
Was this tutorial helpful?