Understanding JVM Safepoints: Concepts, Examples, and Tuning
JVM safepoints are pause points where the VM can stop all threads for operations like garbage collection; the article shows how counted loops can prevent threads from reaching safepoints, causing unexpected long sleeps, and explains tuning flags, loop‑counter changes, and best practices to avoid STW pauses.
This article introduces the concept of JVM safepoints, originally encountered in the book "Deep Understanding of the Java Virtual Machine". Safepoints are specific locations where the JVM can pause all Java threads (Stop‑The‑World) to perform operations such as garbage collection.
Key points from the initial overview:
JVM inserts safepoints at method calls, loop jumps, and exception jumps.
Threads are stopped at safepoints via an active‑interrupt flag set by the VM.
Modern JVMs use active‑interrupt (polling) rather than pre‑emptive interruption.
The article then presents a simple Java program to demonstrate unexpected blocking of the main thread:
public class SafePointTest {
public static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) throws Exception{
long startTime = System.currentTimeMillis();
Runnable runnable = () -> {
System.out.println(interval(startTime) + "ms后," + Thread.currentThread().getName() + "子线程开始运行");
for(int i = 0; i < 100000000; i++) {
counter.getAndAdd(1);
}
System.out.println(interval(startTime) + "ms后," + Thread.currentThread().getName() + "子线程结束运行, counter=" + counter);
};
Thread t1 = new Thread(runnable, "zz-t1");
Thread t2 = new Thread(runnable, "zz-t2");
t1.start();
t2.start();
System.out.println(interval(startTime) + "ms后,主线程开始sleep.");
Thread.sleep(1000L);
System.out.println(interval(startTime) + "ms后,主线程结束sleep.");
System.out.println(interval(startTime) + "ms后,主线程结束,counter:" + counter);
}
private static long interval(Long startTime) {
return System.currentTimeMillis() - startTime;
}
}When run with default JVM options, the main thread sleeps far longer than the requested 1 second because it is forced to wait for the two child threads to reach a safepoint.
Verification steps:
Enable safepoint statistics with -XX:+PrintSafepointStatistics and observe logs showing a "no vm operation" safepoint that waited ~2251 ms for the two child threads.
Adding -XX:+SafepointTimeout and -XX:SafepointTimeoutDelay=2000 reveals which threads blocked.
Why does this happen?
The VM periodically forces a global safepoint (default interval 1 s via -XX:GuaranteedSafepointInterval ). The main thread reaches a safepoint inside Thread.sleep , a native method that checks the poll flag.
The child threads use an int loop, which the JVM treats as a "counted loop" and does not insert a safepoint, so they stay out of the safepoint for several seconds.
Solutions explored:
Disable periodic safepoints with -XX:GuaranteedSafepointInterval=0 – the main thread finishes after 1 s.
Increase the interval (e.g., to 5000 ms) – same effect.
Change the loop index to long (an "uncountable" loop) – a safepoint is inserted and the child threads no longer block the main thread.
Disable counted‑loop safepoints with -XX:+UseCountedLoopSafepoints – also resolves the issue.
The article also discusses JIT optimization: with JIT enabled, the native AtomicInteger.getAndAdd call is inlined and does not create a safepoint, whereas disabling JIT ( -Djava.compiler=NONE ) makes the main thread resume promptly but slows the child threads.
A broader definition of safepoints is provided: they are points where a thread’s state is well‑defined, allowing the VM to safely inspect or modify thread stacks, perform GC, de‑optimize code, or handle other VM operations.
Typical triggers for safepoints include:
Garbage collection (Stop‑The‑World).
Periodic safepoint interval.
Diagnostic commands such as jstack , jmap , jstat .
Biased‑lock revocation.
Agent loading / class redefinition.
JIT code cache management.
To avoid the performance impact of long STW pauses, the article recommends:
Use long loop counters for large loops.
Consider disabling biased locking ( -XX:-UseBiasedLocking ).
Turn off thread‑dump generation in production.
References are listed at the end of the article.
DeWu Technology
A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.