小师妹学JVM之:JVM中的Safepoints
文章目錄
- 簡介
- GC的垃圾回收器
- 分代回收器中的問題
- safepoints
- safepoint一般用在什么地方
- 總結(jié)
簡介
java程序員都聽說過GC,大家也都知道GC的目的是掃描堆空間,然后將那些標(biāo)記為刪除的對(duì)象從堆空間釋放,以提升可用的堆空間。今天我們會(huì)來探討一下隱藏在GC背后的一個(gè)小秘密Safepoints。
GC的垃圾回收器
小師妹:F師兄,GC的垃圾回收器的種類為什么會(huì)有這么多呀?使用起來不是很麻煩。并且我聽說CMS在JDK9zhong已經(jīng)被廢棄了。
小師妹,這么多垃圾回收器實(shí)際是在JVM的發(fā)展過程中建立起來的,在之前的文章中,我們講到了目前的GC回收器有這樣幾種。
Concurrent mark sweep (CMS) ,CMS是mark and swap的升級(jí)版本,它使用多個(gè)線程來對(duì)heap區(qū)域進(jìn)行掃描,從而提升效率。
由于CMS的參數(shù)復(fù)雜性和性能問題,CMS已經(jīng)在JDK9中被廢棄了。
Serial garbage collection,使用單一的線程來進(jìn)行垃圾回收操作,其好處就是不需要和其他的線程進(jìn)行交互。如果你是單核的CPU,那么最好就是選擇Serial garbage collection,因?yàn)槟悴荒艹浞掷枚嗪说暮锰帯M瑯拥乃渤3S迷诒容^小型的項(xiàng)目中。
Parallel garbage collection,如果你是多核處理器,那么Parallel GC可能是你的選擇。
Parallel GC是JDK8中的默認(rèn)GC。而在JDK9之后, G1是默認(rèn)的GC。
G1 garbage collection,G1=Garbage First,它是為替換CMS而生的,最早出現(xiàn)在java7中。
G1將heap區(qū)域劃分成為多個(gè)更小的區(qū)域,每個(gè)小區(qū)域都被標(biāo)記成為young generation 或者old generation。從而運(yùn)行GC在更小的范圍里運(yùn)行,而不是影響整個(gè)heap區(qū)域。
Z Garbage Collection,ZGC是一個(gè)可擴(kuò)展的,低延遲的GC。ZGC是并發(fā)的,而且不需要停止正在運(yùn)行的線程。
ZGC是在JDK11中引入的。
當(dāng)然還有正在研發(fā)中的其他GC。
更多精彩內(nèi)容且看:
- 區(qū)塊鏈從入門到放棄系列教程-涵蓋密碼學(xué),超級(jí)賬本,以太坊,Libra,比特幣等持續(xù)更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續(xù)更新
- Spring 5.X系列教程:滿足你對(duì)Spring5的一切想象-持續(xù)更新
- java程序員從小工到專家成神之路(2020版)-持續(xù)更新中,附詳細(xì)文章教程
分代回收器中的問題
小師妹:F師兄,分代回收器不好嗎?為什么還有新的ZGC等基于非分代技術(shù)的回收器?
分代垃圾回收器中有一個(gè)非常常見的現(xiàn)象就是"Stop The World"。什么是Stop the world呢?
就是說在GC的時(shí)候,為了進(jìn)行垃圾回收,需要所有的線程都要暫停執(zhí)行。所有的線程都暫停執(zhí)行。
當(dāng)然G1雖然是基于分代技術(shù),但是G1實(shí)際上是不會(huì)"Stop The World"的。
JVM定義了一些Root對(duì)象,從這些對(duì)象開始,找出他們引用的對(duì)象,組成一個(gè)對(duì)象圖。所有在這個(gè)圖里面的對(duì)象都是有效的對(duì)象,反之不在對(duì)象圖中的對(duì)象就應(yīng)該被回收。有效的對(duì)象將會(huì)被Mark為alive。
這些Root對(duì)象包括:正在執(zhí)行的方法中的本地對(duì)象和輸入?yún)?shù)。活動(dòng)的線程,加載類中的static字段和JNI引用。
safepoints
為了實(shí)現(xiàn)STW的功能,JVM需要提供一個(gè)機(jī)制,讓所有的線程可以在某一個(gè)時(shí)刻同時(shí)停下來。這個(gè)停下來的時(shí)刻就叫做safepoints。
注意,這些停下來的線程不包括運(yùn)行native code的線程。因?yàn)檫@些線程是不屬于JVM管理的。
JVM中的代碼執(zhí)行其實(shí)有兩種方式,一種是JIT編譯成為機(jī)器碼,一種是解釋執(zhí)行。
在JIT中,直接將檢查代碼編譯進(jìn)入了機(jī)器碼中。通過設(shè)置相應(yīng)的標(biāo)記位,從而在線程運(yùn)行的過程中執(zhí)行暫停的指令。
還是舉一個(gè)上篇文章中我們提到的JMH的例子:
@Benchmarkpublic void test1() {int length = array.length;for (int i = 0; i < length; i=i+1)array[i] ++;}我們看一下它的assembly code:
可以看到其中有個(gè)test的指令,這個(gè)test指令就是生成的safe points。
通過設(shè)置標(biāo)志位,就可以在線程運(yùn)行時(shí)執(zhí)行暫停操作。
如果是解釋執(zhí)行的話,JVM保存了兩個(gè)字節(jié)碼的調(diào)度table,當(dāng)需要safepoint的時(shí)候,JVM就進(jìn)行table的切換,從而開啟safepoint。
safepoint一般用在什么地方
一般情況下,GC,JIT的反代碼優(yōu)化,刷新code cache,類重定義 ,偏向鎖撤銷和其他的一些debug操作。
我們可以通過使用-XX:+PrintGCApplicationStoppedTime來print safepints的暫停時(shí)間。
-XX:+PrintSafepointStatistics –XX:PrintSafepointStatisticsCount=1這兩個(gè)參數(shù)可以強(qiáng)制JVM打印safepoint的一些統(tǒng)計(jì)信息。
總結(jié)
Safepoint是垃圾回收中一個(gè)非常重要的概念,希望大家能夠有所了解。
本文作者:flydean程序那些事
本文鏈接:http://www.flydean.com/jvm-jit-safepoints/
本文來源:flydean的博客
歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您!
總結(jié)
以上是生活随笔為你收集整理的小师妹学JVM之:JVM中的Safepoints的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小师妹学JVM之:cache line对
- 下一篇: 小师妹学JVM之:Dirty cards