一文了解JDK12 13 14 GC調優祕籍-附PDF下載

簡介

想了解JDK12,13,14中的GC調優祕籍嗎?想知道這三個版本中JVM有什麼新的變化嗎?java

一塊兒來看看這期的GC調優祕籍,由於JDK12,13,14中的GC變化不太大,因此這裏一塊兒作個總結,文末附有相應的PDF下載,但願你們可以喜歡。linux

那些好用的VM參數

咱們再講幾個以前的版本中沒有講過的比較好用的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。咱們試一下:

是否是很是有用?

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程序那些事

本文連接:http://www.flydean.com/jdk12-13-14-gc-cheatsheet/

本文來源:flydean的博客

歡迎關注個人公衆號:程序那些事,更多精彩等着您!

相關文章
相關標籤/搜索