一張PDF了解JDK10 GC調優秘籍-附PDF下載

簡介

今天我們講講JDK10中的JVM GC調優參數,JDK10中JVM的參數總共有1957個,其中正式的參數有658個。

其實JDK10跟JDK9相比沒有太大的變化,一個我們可以感受到的變化就是引入了本地變數var。

為了方便大家的參考,特意將JDK10中的GC參數總結成了一張PDF,這個PDF在之前的JDK9的基礎上進行了增減和修正,歡迎大家下載。

Java參數類型

其實Java參數類型可以分為三類。

第一類叫做標準的java參數。

這一類參數是被所有的JVM實現所支援的,是一些非常常用的JVM參數。

我們可以通過直接執行java命令來查看。

第二類叫做額外的java參數,這些參數是專門為Hotspot VM準備的,並不保證所有的JVM都實現了這些參數。並且這些參數隨時有可能被修改。 額外的java參數是以 -X開頭的。

我們可以通過java -X來查看。

第三類叫做高級參數。這些參數是開發者選項,主要作用就是JVM調優。這些參數和第二類參數一樣,也是不保證被所有的JVM支援的,並且隨時都可能變化。

第三類參數是以-XX開頭的,我們可以通過java -XX:+PrintFlagsFinal來查看。

神奇的是,我們做JVM調優的參數往往就是這第三類參數,所以,下次如果再有面試官問你JVM調優,你可以直接懟回去:這些參數是不被官方推薦普通使用者使用的,並且隨時都可能變化。沒必要掌握!那麼這個Offer肯定非你莫屬。

Large Pages

其實JDK10跟JDK9相比沒啥大的變化,這裡重點講解一個特性叫做Large Pages。

Large pages其實不是JDK10的新特性了,它的歷史已經很久了。

在講large Pages之前,我們先講一下記憶體分頁。

CPU是通過定址來訪問記憶體空間的。一般來說CPU的定址能力是有限的。而實際的物理記憶體地址會遠大於CPU的定址範圍。

為了解決這個問題,現代CPU引入了MMU(Memory Management Unit 記憶體管理單元)和虛擬地址空間的概念。

虛擬地址空間也叫做(Virtual address space),為了不同程式的互相隔離和保證程式中地址的確定性,現代電腦系統引入了虛擬地址空間的概念。簡單點講可以看做是跟實際物理地址的映射,通過使用分段或者分頁的技術,將實際的物理地址映射到虛擬地址空間。

同時為了解決虛擬空間比物理記憶體空間大的問題,現代電腦技術一般都是用了分頁技術。

分頁技術就是將虛擬空間分為很多個page,只有在需要用到的時候才為該page分配到物理記憶體的映射,這樣物理記憶體實際上可以看做虛擬空間地址的快取。

虛擬地址空間和物理地址的映射是通過一個叫做映射存儲表的地方來工作的。這個地方一般被叫做頁表(page table),頁表是存儲在物理記憶體中的。

CPU讀取物理記憶體速度肯定會慢於讀取暫存器的速度。於是又引入了TLB的概念。

Translation-Lookaside緩衝區(TLB)是一個頁面轉換快取,其中保存了最近使用的虛擬到物理地址轉換。

TLB容量是有限的。如果發生TLB miss則需要CPU去訪問記憶體中的頁表,從而造成性能損耗。

通過調大記憶體分頁大小,單個TLB條目存儲更大的記憶體範圍。這將減少對TLB的壓力,並且對記憶體密集型應用程式可能具有更好的性能。

但是,大頁面也可能會對系統性能產生負面影響。例如,當應用程式使用大量大頁面記憶體時,可能會導致常規記憶體不足,並導致其他應用程式中的過多分頁,並使整個系統變慢。同樣,長時間運行的系統可能會產生過多的碎片,這可能導致無法保留足夠大的頁面記憶體。發生這種情況時,OS或JVM都會恢復為使用常規頁面。

Oracle Solaris, Linux, and Windows Server 2003 都支援大頁面。

具體各個系統的large page的配置,大家可以自行探索。

JIT調優

JIT我在之前的文章中介紹過很多次了,為了提升java程式的執行效率,JVM會將部分熱點程式碼,使用JIT編譯成為機器碼。

那麼JIT的調試參數也是非常重要的。這裡具體講解一些比較常用JIT調試指令:

-XX:+BackgroundCompilation

使用後台編譯,也就是說編譯執行緒和前台執行緒使用是不同的執行緒。一般來說如果我們需要調試JIT日誌的話,需要關閉此選項。

-XX:CICompilerCount=threads

設置編譯執行緒的個數。

-XX:CompileCommand=command,method[,option]

自定義具體方法的編譯方式。

比如:

-XX:CompileCommand=exclude,java/lang/String.indexOf

意思是把String的indexOf exclude from compiled。

這裡的command有下面幾種:

  • break – 為編譯設置斷點
  • compileonly – exclude所有的方法,除了指定的方法
  • dontinline – 指定的方法不inline
  • exclude – 編譯的時候排除指定的方法
  • inline – inline指定的方法
  • log – exclude所有的方法日誌,除了指定的方法
  • option – 傳遞一個JIT編譯的參數
  • print – 輸出生成的彙編程式碼
  • quiet – 不列印編譯命令
-XX:CompileOnly=methods

指定編譯某些命令。

-XX:CompileThreshold=invocations

命令經過多少次解釋執行,才會被編譯。默認情況下在-server模式,這個值是10,000, 在-client模式,這個值是1,500。

如果分層編譯開啟之後,這個值會被忽略。

-XX:+DoEscapeAnalysis

開啟逃逸分析。

-XX:+Inline

開啟inline特性。

-XX:+LogCompilation

輸出編譯日誌。

-XX:+PrintAssembly

輸出彙編程式碼。

-XX:-TieredCompilation

取消分層編譯。

上圖:

總結

同樣的,為JDK10特意準備了一個PDF,下載鏈接如下:

JDK10GC-cheatsheet.pdf

本文鏈接://www.flydean.com/jdk10-gc-cheatsheet/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!