想了解JDK12,13,14中的GC調優祕籍嗎?想知道這三個版本中JVM有什麼新的變化嗎?java
一塊兒來看看這期的GC調優祕籍,由於JDK12,13,14中的GC變化不太大,因此這裏一塊兒作個總結,文末附有相應的PDF下載,但願你們可以喜歡。linux
咱們再講幾個以前的版本中沒有講過的比較好用的VM參數。git
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=path
咱們寫java程序的,常常會碰到程序報java.lang.OutOfMemoryError異常,這時候優秀的咱們是怎麼解決的呢?程序員
高級程序員一看到這個錯誤,就知道heap空間不夠用了,加大heap空間吧。github
可是聰明的程序員可能就會問了,爲何會出現這個OutOfMemoryError異常呢?是否是咱們程序裏面有沒有問題呢?windows
帶着這個疑問,聰明的程序員可能會使用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。咱們試一下:
是否是很是有用?
JVM在發展,G1的參數也在發展,這幾個版本中有幾個G1的參數名發生了變化:
-XX:DefaultMaxNewGenPercent 替換成爲-XX:G1MaxNewSizePercent=percent
-XX:G1OldCSetRegionLiveThresholdPercent 替換成爲-XX:G1MixedGCLiveThresholdPercent=percent
-XX:DefaultMinNewGenPercent替換成爲-XX:G1NewSizePercent=percent
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
默認狀況下,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的體驗了。ZGC是一個可擴展的,低延遲的GC。ZGC是併發的,並且不須要中止正在運行的線程。
ZGC是在JDK11中被引入的。
咱們經過下面的方式來開啓ZGC:
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
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程序那些事本文連接:http://www.flydean.com/jdk12-13-14-gc-cheatsheet/
本文來源:flydean的博客
歡迎關注個人公衆號:程序那些事,更多精彩等着您!