1. 程式人生 > >小師妹學JVM之:JVM中的Safepoints

小師妹學JVM之:JVM中的Safepoints

[toc] # 簡介 java程式設計師都聽說過GC,大家也都知道GC的目的是掃描堆空間,然後將那些標記為刪除的物件從堆空間釋放,以提升可用的堆空間。今天我們會來探討一下隱藏在GC背後的一個小祕密Safepoints。 # GC的垃圾回收器 小師妹:F師兄,GC的垃圾回收器的種類為什麼會有這麼多呀?使用起來不是很麻煩。並且我聽說CMS在JDK9zhong已經被廢棄了。 小師妹,這麼多垃圾回收器實際是在JVM的發展過程中建立起來的,在之前的文章中,我們講到了目前的GC回收器有這樣幾種。 1. 基於分代技術的回收器 Concurrent mark sweep (CMS) ,CMS是mark and swap的升級版本,它使用多個執行緒來對heap區域進行掃描,從而提升效率。 > 由於CMS的引數複雜性和效能問題,CMS已經在JDK9中被廢棄了。 Serial garbage collection,使用單一的執行緒來進行垃圾回收操作,其好處就是不需要和其他的執行緒進行互動。如果你是單核的CPU,那麼最好就是選擇Serial garbage collection,因為你不能充分利用多核的好處。同樣的它也常常用在比較小型的專案中。 Parallel garbage collection,如果你是多核處理器,那麼Parallel GC可能是你的選擇。 > Parallel GC是JDK8中的預設GC。而在JDK9之後, G1是預設的GC。 G1 garbage collection,G1=Garbage First,它是為替換CMS而生的,最早出現在java7中。 G1將heap區域劃分成為多個更小的區域,每個小區域都被標記成為young generation 或者old generation。從而執行GC在更小的範圍裡執行,而不是影響整個heap區域。 2. 非基於分代技術的回收器 Z Garbage Collection,ZGC是一個可擴充套件的,低延遲的GC。ZGC是併發的,而且不需要停止正在執行的執行緒。 > ZGC是在JDK11中引入的。 當然還有正在研發中的其他GC。 # 分代回收器中的問題 小師妹:F師兄,分代回收器不好嗎?為什麼還有新的ZGC等基於非分代技術的回收器? 分代垃圾回收器中有一個非常常見的現象就是"Stop The World"。什麼是Stop the world呢? 就是說在GC的時候,為了進行垃圾回收,需要所有的執行緒都要暫停執行。所有的執行緒都暫停執行。 當然G1雖然是基於分代技術,但是G1實際上是不會"Stop The World"的。 JVM定義了一些Root物件,從這些物件開始,找出他們引用的物件,組成一個物件圖。所有在這個圖裡面的物件都是有效的物件,反之不在物件圖中的物件就應該被回收。有效的物件將會被Mark為alive。 這些Root物件包括:正在執行的方法中的本地物件和輸入引數。活動的執行緒,載入類中的static欄位和JNI引用。 # safepoints 為了實現STW的功能,JVM需要提供一個機制,讓所有的執行緒可以在某一個時刻同時停下來。這個停下來的時刻就叫做safepoints。 > 注意,這些停下來的執行緒不包括執行native code的執行緒。因為這些執行緒是不屬於JVM管理的。 JVM中的程式碼執行其實有兩種方式,一種是JIT編譯成為機器碼,一種是解釋執行。 在JIT中,直接將檢查程式碼編譯進入了機器碼中。通過設定相應的標記位,從而線上程執行的過程中執行暫停的指令。 還是舉一個上篇文章中我們提到的JMH的例子: ~~~java @Benchmark public void test1() { int length = array.length; for (int i = 0; i < length; i=i+1) array[i] ++; } ~~~ 我們看一下它的assembly code: ![](https://img-blog.csdnimg.cn/20200703202258733.png) 可以看到其中有個test的指令,這個test指令就是生成的safe points。 通過設定標誌位,就可以線上程執行時執行暫停操作。 如果是解釋執行的話,JVM儲存了兩個位元組碼的排程table,當需要safepoint的時候,JVM就進行table的切換,從而開啟safepoint。 # safepoint一般用在什麼地方 一般情況下,GC,JIT的反程式碼優化,重新整理code cache,類重定義 ,偏向鎖撤銷和其他的一些debug操作。 我們可以通過使用-XX:+PrintGCApplicationStoppedTime來print safepints的暫停時間。 -XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1這兩個引數可以強制JVM列印safepoint的一些統計資訊。 # 總結 Safepoint是垃圾回收中一個非常重要的概念,希望大家能夠有所瞭解。 >
本文作者:flydean程式那些事 > > 本文連結:[http://www.flydean.com/jvm-jit-safepoints/](http://www.flydean.com/jvm-jit-safepoints/) > > 本文來源:flydean的部落格 > > 歡迎關注我的公眾號:程式那些事,更多精彩等著您!