1. 程式人生 > >JVM系列之:再談java中的safepoint

JVM系列之:再談java中的safepoint

[toc] # safepoint是什麼 java程式裡面有很多很多的java執行緒,每個java執行緒又有自己的stack,並且共享了heap。這些執行緒一直執行呀執行,不斷對stack和heap進行操作。 這個時候如果JVM需要對stack和heap做一些操作該怎麼辦呢? 比如JVM要進行GC操作,或者要做heap dump等等,這時候如果執行緒都在對stack或者heap進行修改,那麼將不是一個穩定的狀態。GC直接在這種情況下操作stack或者heap,會導致執行緒的異常。 怎麼處理呢? 這個時候safepoint就出場了。 safepoint就是一個安全點,所有的執行緒執行到安全點的時候就會去檢查是否需要執行safepoint操作,如果需要執行,那麼所有的執行緒都將會等待,直到所有的執行緒進入safepoint。 然後JVM執行相應的操作之後,所有的執行緒再恢復執行。 # safepoint的例子 我們舉個例子,一般safepoint比如容易出現在迴圈遍歷的情況,還是使用我們之前做null測試用的例子: ~~~java public class TestNull { public static void main(String[] args) throws InterruptedException { List list= new ArrayList(); list.add("www.flydean.com"); for (int i = 0; i < 10000; i++) { testMethod(list); } Thread.sleep(1000); } private static void testMethod(List list) { list.get(0); } } ~~~ 執行結果如下: ![](https://img-blog.csdnimg.cn/20200703225806755.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_0,text_aHR0cDovL3d3dy5mbHlkZWFuLmNvbQ==,size_35,color_8F8F8F,t_70) 標紅的就是傳說中的safepoint。 # 執行緒什麼時候會進入safepoint 那麼執行緒什麼時候會進入safepoint呢? 一般來說,如果執行緒在競爭鎖被阻塞,IO被阻塞,或者在等待獲得監視器鎖狀態時,執行緒就處於safepoint狀態。 如果執行緒再執行JNI程式碼的哪一個時刻,java執行緒也處於safepoint狀態。因為java執行緒在執行原生代碼之前,需要儲存堆疊的狀態,讓後再移交給native方法。 如果java的位元組碼正在執行,那麼我們不能判斷該執行緒是不是在safepint上。 # safepoint是怎麼工作的 如果你使用的是hotspot JVM,那麼這個safepoint是一個全域性的safepoint,也就是說執行Safepoint需要暫停所有的執行緒。 如果你使用的是Zing,那麼可以線上程級別使用safepoint。 我們可以看到生成的組合語言中safepoint其實是一個test命令。 test指向的是一個特殊的記憶體頁面地址,當JVM需要所有的執行緒都執行到safepint的時候,就會對該頁面做一個標記。從而通知所有的執行緒。 我們再用一張圖來詳細說明: ![](https://img-blog.csdnimg.cn/20200703233056728.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_0,text_aHR0cDovL3d3dy5mbHlkZWFuLmNvbQ==,size_35,color_8F8F8F,t_70) thread1在收到設定safepoint之前是一直執行的,在收到訊號之後還會執行一段時間,然後到達Safepint暫停執行。 thread2先執行了一段時間,然後因為CPU被搶奪,空閒了一段時間,在這段時間裡面,thread2收到了設定safepoint的訊號,然後thread2獲得執行權力,接著繼續執行,最後到達safepoint。 thread3是一個native方法,將會一直執行,知道safepoint結束。 thread4也是一個native方法,它和thread3的區別就在於,thread4在safepoint開始和結束之間結束了,需要將控制器轉交給普通的java執行緒,因為這個時候JVM在執行Safepoint的操作,所以任然需要暫停執行。 在HotSpot VM中,你可以在組合語言中看到safepoint的兩種形式:'{poll}' 或者 '{poll return}' 。 # 總結 本文詳細的講解了JVM中Safepoint的作用,希望大家能夠喜歡。 > 本文作者:flydean程式那些事 > > 本文連結:[http://www.flydean.com/jvm-safepoint2/](http://www.flydean.com/jvm-safepoint2/) > > 本文來源:flydean的部落格 > > 歡迎關注我的公眾號:程式那些事,更多精彩等