一文了解JDK12 13 14 GC調優秘籍-附PDF下載
簡介
想了解JDK12,13,14中的GC調優秘籍嗎?想知道這三個版本中JVM有什麼新的變化嗎?
一起來看看這期的GC調優秘籍,因為JDK12,13,14中的GC變化不太大,所以這裡一起做個總結,文末附有相應的PDF下載,希望大家能夠喜歡。
那些好用的VM參數
我們再講幾個之前的版本中沒有講過的比較好用的VM參數。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=path
我們寫java程式的,經常會碰到程式報java.lang.OutOfMemoryError異常,這時候優秀的我們是怎麼解決的呢?
高級程式設計師一看到這個錯誤,就知道heap空間不夠用了,加大heap空間吧。
但是聰明的程式設計師可能就會問了,為什麼會出現這個OutOfMemoryError異常呢?是不是我們程式裡面有沒有問題呢?
帶著這個疑問,聰明的程式設計師可能會使用jmap命令將heap dump出來,甚至有些程式設計師可以熟練的使用jcmd pid GC.heap_info命令來查看heap info了。
這些都很好,但是如果使用上面兩個JVM選項,程式只要出現OutOfMemoryError,就會自動將heap dump出來,默認的文件名是java_pid.hprof ,你也可以自己指定文件路徑。
-XX:+PrintClassHistogram
有時候,我們需要統計class的資訊,那麼可以使用這個選項。
在windows環境中收到Control+C,或者在linux環境中收到Control+Break訊號的時候就會觸發相應的統計事件。
這個參數和 jmap -histo command 或者 jcmd pid GC.class_histogram效果是一樣的。
有小夥伴要問了,Control+C和Control+Break訊號是什麼鬼?怎麼將訊號傳遞給java程式呢?
這裡給大家擴展講一下,發送訊號可以用kill命令。
kill其實有兩種用法。
第一種 kill pid,kill後面直接跟一個pid。
第二中 kill -TERM pid, TERM就是我們要向kill傳遞的訊號。
其實kill pid 就是 kill -15 pid的簡寫。
我們是用kill -l來看一下kill支援的訊號類型:
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
我們常用的9=SIGKILL,也就是向JVM傳遞一個強制kill的訊號。
注意,這些訊號中,除了9這個訊號可以無條件終止進程,其他的訊號進程都有權利忽略。
所以有時候我們使用kill pid命令去終止進程,但是進程沒反應。不是因為進程壞了,而是因為進程忽略掉了你發出的訊號。
-XX:+PrintConcurrentLocks
同樣的,PrintConcurrentLocks也是收到Control+Break或者Control+C訊號時,輸出java.util.concurrent的lock資訊。
這個參數和jstack -l 或者jcmd pid Thread.print -l效果是一樣的。
-XX:+PrintFlagsRanges
再來看一個比較有用的參數PrintFlagsRanges。有時候我們想使用某些VM的參數,但是不知道這些參數的取值範圍,那麼可以使用PrintFlagsRanges。我們試一下:
是不是非常有用?
G1的變化
JVM在發展,G1的參數也在發展,這幾個版本中有幾個G1的參數名發生了變化:
-XX:DefaultMaxNewGenPercent 替換成為-XX:G1MaxNewSizePercent=percent
-XX:G1OldCSetRegionLiveThresholdPercent 替換成為-XX:G1MixedGCLiveThresholdPercent=percent
-XX:DefaultMinNewGenPercent替換成為-XX:G1NewSizePercent=percent
配置FlightRecorder
Java Flight Recorder(JFR)是JVM的診斷和性能分析工具。它可以收集有關JVM以及在其上運行的Java應用程式的數據。JFR是集成到JVM中的,所以JFR對JVM的性能影響非常小,我們可以放心的使用它。
一般來說,在使用默認配置的時候,性能影響要小於1%。
JFR是一個基於事件的低開銷的分析引擎,具有高性能的後端,可以以二進位格式編寫事件。
JFR是JVM的調優工具,通過不停的收集JVM和java應用程式中的各種事件,從而為後續的JMC分析提供數據。
Event是由三部分組成的:時間戳,事件名和數據。同時JFR也會處理三種類型的Event:持續一段時間的Event,立刻觸發的Event和抽樣的Event。
為了保證性能的最新影響,在使用JFR的時候,請選擇你需要的事件類型。
JFR從JVM中搜集到Event之後,會將其寫入一個小的thread-local快取中,然後刷新到一個全局的記憶體快取中,最後將快取中的數據寫到磁碟中去。
或者你可以配置JFR不寫到磁碟中去,但是這樣快取中只會保存部分events的資訊。
FlightRecorder有兩部分的配置,第一部分是配置FlightRecorder本身的大小,存儲等資訊。第二部分是FlightRecorder的開啟選項。
我們看下FlightRecorder相關的配置參數:
-XX:FlightRecorderOptions:parameter=value
下面是StartFlightRecording的配置:
-XX:StartFlightRecording=parameter=value
RAM參數
默認情況下,JVM的MaxHeapSize是根據RAM的大小來自動配置的,比如說,我有一個8G記憶體的機子,執行下面的命令:
java -XX:+PrintFlagsFinal -version | grep -Ei "maxheapsize|maxram"
可以看到MaxHeapSize= MaxRAM / MaxRAMPercentage。
VM也提供了下面幾個用來設置RAM相關的參數:
-XX:MaxRAM=size
-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage
主要就是設置最大的RAM值和Heap佔RAM的比例。
RAM參數主要是為了java在容器中運行配置的。
JDK13中的ZGC
在JDK13中,我們可以開啟ZGC的體驗了。ZGC是一個可擴展的,低延遲的GC。ZGC是並發的,而且不需要停止正在運行的執行緒。
ZGC是在JDK11中被引入的。
我們通過下面的方式來開啟ZGC:
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
RTM支援
Restricted Transactional Memory(RTM)是受限的事務性存儲器,是Intel在x86微架構中所引入的指令集系統,它屬於TSX(Transactional Synchronization Extensions,事務性同步擴展)指令集擴展。
RTM主要用來在多執行緒環境中提升執行效率。
RTM引入了XBEGIN, XABORT, XEND和XTEST。通過將指令包含在XBEGIN和XEND之間,可以達到transaction的效果。
可以將RTM看做是一個粗粒度的鎖,XBEGIN和XEND之間包含的程式碼就是要執行的程式。RTM可以由硬體自動檢測操作中的數據衝突,保證事務性操作的正確性,從而發掘操作間的並行性。
同時RTM還可以減少CPU cache line的false-sharing。
RTM支援主要有4個參數:
-XX:+UseRTMLocking
-XX:+UseRTMDeopt
-XX:RTMAbortRatio=abort_ratio
-XX:RTMRetryCount=count
其中UseRTMDeopt和RTMAbortRatio是聯合起來用的。
之前我們講到RTM會對粗粒度的鎖進行優化,但如果真的是多執行緒並發執行訪問同樣資源的時候,這個優化實際上是不成功的,會被abort,然後回退到正常的鎖狀態。
如果abort超出了一定的比例,則會將RTM程式碼反優化。
總結
好了,就總結這麼多。下面是JDK12,13,14的GC調優秘籍,歡迎下載。
本文作者:flydean程式那些事
本文鏈接://www.flydean.com/jdk12-13-14-gc-cheatsheet/
本文來源:flydean的部落格
歡迎關注我的公眾號:程式那些事,更多精彩等著您!