int i = 0; while (i<10000000) { // business logic //prevent long time gc if (i % 3000 == 0) { try { Thread.sleep(0); } catch (InterruptedException e) { e.printStackTrace(); } } }sleep了 0 秒,不就是不睡觉吗?我的第一反应是这段代码没什么用,但是看到他的注释又引起了我的兴趣。经过一番研究,看似无用的一段代码,其实大有文章。
以HotSpot虚拟机为例,JVM 并不会在代码指令流的任何位置暂停以启动垃圾回收,而是强制执行必须到达安全点才暂停。换句话说,在到达安全点之前,JVM 不会为 GC STOP THE WORLD。
// Begin the process of bringing the system to a safepoint. // Java threads can be in several different states and are // stopped by different mechanisms: // // 1. Running interpreted // The interpeter dispatch table is changed to force it to // check for a safepoint condition between bytecodes. // 2. Running in native code // When returning from the native code, a Java thread must check // the safepoint _state to see if we must block. If the // VM thread sees a Java thread in native, it does // not wait for this thread to block. The order of the memory // writes and reads of both the safepoint state and the Java // threads state is critical. In order to guarantee that the // memory writes are serialized with respect to each other, // the VM thread issues a memory barrier instruction // (on MP systems). In order to avoid the overhead of issuing // a memory barrier for each Java thread making native calls, each Java // thread performs a write to a single memory page after changing // the thread state. The VM thread performs a sequence of // mprotect OS calls which forces all previous writes from all // Java threads to be serialized. This is done in the // os::serialize_thread_states() call. This has proven to be // much more efficient than executing a membar instruction // on every call to native code. // 3. Running compiled Code // Compiled code reads a global (Safepoint Polling) page that // is set to fault if we are trying to get to a safepoint. // 4. Blocked // A thread which is blocked will not be allowed to return from the // block condition until the safepoint operation is complete. // 5. In VM or Transitioning between states // If a Java thread is currently running in the VM or transitioning // between states, the safepointing code will wait for the thread to // block itself when it attempts transitions to a new state.可以看上面的第 2 点 Running in native code,而Thread.sleep(long millis)是一种native方法。