1. 程式人生 > >秒懂JVM的三大引數型別,就靠這十個小實驗了

秒懂JVM的三大引數型別,就靠這十個小實驗了

![封面](http://cdn.jayh.club/blog/20200915/64RykjzQjHkQ.png?imageslim) # 秒懂JVM的三大引數型別,就靠這十個小實驗了 ![mark](http://cdn.jayh.club/blog/20200915/64RykjzQjHkQ.png?imageslim) > 你好,我是悟空哥,「7年專案開發經驗,全棧工程師,開發組長,超喜歡圖解程式設計底層原理」。手寫了2個小程式,Java刷題小程式,PMP刷題小程式,已釋出到公眾號選單。 > SpringCloud實戰專案[Github](https://github.com/Jackson0714/PassJava-Platform) > Java線上文件[Github](https://github.com/Jackson0714/PassJava-Learning) 本實驗的目的是講解JVM的三大引數型別。在JVM調優中用到的最多的XX引數,而如何去檢視和設定JVM的XX引數也是調優的基本功,本節以實驗的方式講解JVM引數的檢視和設定。希望大家能有所啟發。
## 標配引數 ### 常見標配引數 - -version,獲取JDK版本 - -help,獲取幫助 - -showverision,獲取JDK版本和幫助 ### 動手實驗 1 - 檢視標配引數 實驗步驟: - 檢視Java JDK 版本 ``` java java -version ``` ![實驗 1-1](http://cdn.jayh.club/blog/20200915/kh8gIaaDNWcO.png?imageslim) 可以看到Java JDK 版本為1.8.0_131 - 檢視 Java 幫助文件 ``` JAVA java -help ``` ![實驗 1-2](http://cdn.jayh.club/blog/20200915/LrdkQchIeA68.png?imageslim) - 檢視版本和幫助文件 ``` java java -showversion ``` ![實驗 1-3](http://cdn.jayh.club/blog/20200915/m071zNL09FWL.png?imageslim) ## X引數 ### X引數簡介 我們常用的`javac`大家都知道是把java程式碼編譯成class文java檔案,那麼class檔案怎麼去執行呢?這裡用到了三個X引數來說明class檔案怎麼在虛擬機器裡面跑起來的。 - -Xint:直接解釋執行 - -Xcomp:先編譯成原生代碼再執行 - -XMixed:混合模式(既有編譯執行也有解釋執行) ### 動手實驗 2 - 檢視和配置X引數 - 檢視版本 ``` shell java -version ``` 在WebIDE的控制檯視窗執行java -version後,可以看到我的環境是混合模式執行java程式的。 ![實驗 2-1](http://cdn.jayh.club/blog/20200915/WilmN3z594lS.png?imageslim) - 修改編譯模式為解釋執行模式 ``` sh java -Xint -version ``` 在WebIDE的控制檯視窗執行命令 ![實驗 2-2](http://cdn.jayh.club/blog/20200915/Vw6LnUFlAoV4.png?imageslim) - 修改編譯模式為只編譯模式 ``` sh java -Xcomp -version ``` ![實驗 2-3](http://cdn.jayh.club/blog/20200915/WfCWww8QPPey.png?imageslim) ## XX 引數 ### XX引數簡介 XX引數有兩種型別,一種是Boolean型別,另外一種是鍵值對型別。 - Boolean 型別 - 公式:`-XX:+某個屬性` 或者,`-XX:-某個屬性` +表示開啟了這個屬性,-表示關閉了這個屬性。 - 案例:`-XX:-PrintGCDetails`,表示關閉了GC詳情輸出 - key-value型別 - 公式:`-XX:屬性key=屬性value` - 案例:`-XX:屬性metaspace=2000000`,設定Java元空間的值為2000000。 ### 動手實驗 3 - 檢視引數是否開啟 本實驗主要講解如下內容:檢視執行的Java程式PrintGCDetails引數是否開啟 - 編寫一個一直執行的Java程式 - 檢視該應用程式的程序id - 檢視該程序的GCDetail引數是否開啟 #### 在 WEBIDE 上右鍵單擊選單,選擇 New File 建立新檔案 ![New File](http://cdn.jayh.club/blog/20200915/LqSg8Wfv4Q0N.png?imageslim) #### 建立檔名為 demoXXparam.java ![demoXXparam.java](http://cdn.jayh.club/blog/20200915/l7S79mJGxMyW.png?imageslim) #### 在 WebIDE 上編寫 demoXXparam.java ``` JAVA public class demoXXparam { public static void main(String[] args) throws InterruptedException { System.out.println("hello XX params"); Thread.sleep(Integer.MAX_VALUE); } } ``` #### 在 WebIDE 的控制檯視窗編譯 demoXXparam.java 程式碼 ```java javac demoXXparam.java ``` ![編譯程式碼](http://cdn.jayh.club/blog/20200915/LfePCqTuPfw8.png?imageslim) 編譯之後,會在當前資料夾產生我們所編寫的 `demoXXparam` 類的 `demoXXparam.class` 位元組碼檔案 ![生產Class檔案](http://cdn.jayh.club/blog/20200915/JHN788srztv4.png?imageslim) #### 在 WebIDE 上執行 demoXXparam 程式碼 ``` java java demoXXparam ``` ![執行Java程式](http://cdn.jayh.club/blog/20200915/nEMy2HVmtvn5.png?imageslim) 輸出: ``` SH hello XX params ``` ### 在 WebIDE 中新開一個控制檯視窗 Terminal->
New Terminal ![開啟新控制檯視窗](http://cdn.jayh.club/blog/20200915/EMXBB1AclsiR.png?imageslim) #### 檢視所有的執行的java程式,-l 表示打印出class檔案的包名 ``` JAVA jps -l ``` ![jps](http://cdn.jayh.club/blog/20200915/Oyv9PTQLyn6F.png?imageslim) 發現`demoXXparam`程序的id為 518 #### 檢視 demoXXparam 程式是否開啟了PrintGCDetails這個引數 **PrintGCDetails:** 在發生垃圾回收時列印記憶體回收日誌,並在程序退出時輸出當前記憶體各區域分配情況 ``` SH jinfo -flag PrintGCDetails 518 ``` ![jinfo](http://cdn.jayh.club/blog/20200915/omoVEe2GINuu.png?imageslim) 結果如下: ``` SH -XX:-PrintGCDetails ``` 上面提到 `- `號表示關閉,所以當前 demo 程式沒有開啟 `PrintGCDetails`引數。 ### 動手實驗 4 - 開啟引數 - 在 WebIDE 控制檯強制退出demoXXparam程式 ``` sh ctrl + c ``` - 然後清理螢幕 ``` sh clear ``` - 然後以引數 `-XX:+PrintGCDetails` 執行 demoXXparam 程式 ``` sh java -XX:+PrintGCDetails demoXXparam ``` ![實驗 4](http://cdn.jayh.club/blog/20200915/MOgivWNJrU2h.png?imageslim) - 輸出: ```sh hello XX params ``` #### 檢視demoXXparam程序的 id ![程序 id](http://cdn.jayh.club/blog/20200915/AnyM84Hm6ssL.png?imageslim) 可以看到demoXXparam程序 id 為 1225 #### 檢視 demoXXparam 的配置引數 PrintGCDetails 開啟一個新的控制檯視窗,執行以下命令來檢視程序為 1225 的 `PrintGCDetails`引數是否開啟 ``` sh jinfo -flag PrintGCDetails 1225 ``` ![PrintGCDetails 引數](http://cdn.jayh.club/blog/20200915/Aq86jo99LesY.png?imageslim) 可以看到PrintGCDetails是開啟的,`+`號表示開啟。 ### 動手實驗 5 - Key-Value 型別引數值 #### 檢視元空間的值 ``` sh jinfo -flag MetaspaceSize 526 ``` ![MetaspaceSize 大小](http://cdn.jayh.club/blog/20200915/gnLKSvpUHs9u.png?imageslim) 由此可以得出元空間的大小為 21 M。 #### 設定元空間的值為 128 M ```sh java -XX:MetaspaceSize=128m demoXXparam ``` 檢視元空間的大小 ``` sh jinfo -flag MetaspaceSize 1062 ``` ![調整元空間大小](http://cdn.jayh.club/blog/20200915/UkLaR8mWA3ci.png?imageslim) ## 最常見的 -Xms 和 -Xmx 屬於哪種引數? - -Xms引數代表-XX:InitialHeapSize ,初始化堆記憶體(預設只會用最大實體記憶體的64分1) - -Xmx:引數代表-XX:MaxHeapSize ,大堆記憶體(預設只會用最大實體記憶體的4分1) 起了別名,但還是屬於XX引數。 ### 動手實驗 6 - 設定 -XX:InitialHeapSize 和 -XX:MaxHeapSize 的值。 ``` sh java -XX:InitialHeapSize=200m demoXXparam 或者 java -Xms200m demoXXparam ``` 檢視 InitialHeapSize 引數的值,大小為 200 M。 ![設定 InitialHeapSize](http://cdn.jayh.club/blog/20200915/cFPq3SXFaYhj.png?imageslim) ``` sh java -XX:MaxHeapSize=200M demoXXparam 或者 java -Xmx200m demoXXparam ``` 檢視 MaxHeapSize 引數的值,大小為 200 M。 ![設定 MaxHeapSize](http://cdn.jayh.club/blog/20200915/6gSgjOIrxPeQ.png?imageslim) ### 擴充套件:檢視 Java 程式已設定的所有引數值 ``` sh jinfo -flags <程序id> ``` ![mark](http://cdn.jayh.club/blog/20200915/JvPXocfjcNrD.png?imageslim) - Non-Defalut VM flags 代表引數型別是JVM自帶的引數。 - Command line 代表是使用者自定義的引數 ## 如何查看出廠設定和自定義設定的XX配置項 ### 動手實驗 7 - 查看出廠預設設定的所有XX配置項 ``` sh java -XX:+PrintFlagsInitial -version ``` ![PrintFlagsInitial](http://cdn.jayh.club/blog/20200915/xpiHl2QULIbI.png?imageslim) ### 動手實驗 8 - 檢視 JVM 當前所有XX配置項 ``` sh java -XX:+PrintFlagsFinal -version ``` ![PrintFlagsFinal](http://cdn.jayh.club/blog/20200915/KWTbx4Qi0krm.png?imageslim) 我們可以看到幾個關鍵資訊: - `[Global flags]`:全域性引數,如果自定義修改了某個應用的引數,並不會修改全域性引數 比如之前我們修改了MetaspaceSize為128m,但列表裡面還是21m。 ![Global flags](http://cdn.jayh.club/blog/20200915/UbnXulH9GdUa.png?imageslim) - `:=`:引數已被修改,如下圖所示InitialHeapSize初始化堆記憶體引數已修改為264241152 總結如下: ![出廠設定和自定義引數設定](http://cdn.jayh.club/blog/20200915/yWaE4B437bXk.png?imageslim) ### 動手實驗 9 - 執行程式時列印XX配置選項 ``` sh java -XX:+PrintFlagsFinal -XX:+InitialHeapSize=150M demoXXparam ``` 可以看到修改後的值為 157286400(150 M) ![執行程式時列印XX配置選項](http://cdn.jayh.club/blog/20200915/NQ6Q9szVKbvq.png?imageslim) ### 動手實驗 10 - 檢視 JVM 自動配置的或者使用者手動設定的XX選項(非應用程式的) ``` java java -XX:+PrintCommandLineFlags -version ``` 會打印出如下引數: ![JVM 自動配置的XX選項](http://cdn.jayh.club/blog/20200915/sqztVGrgOkYm.png?imageslim) ## 實驗總結 本節實驗課學習瞭如何檢視基本引數、X引數、XX引數和設定XX引數。以及用好jps和jinfo工具來檢視程序和設定引數。 **JVM效能調優** 還有很多要講的,一篇是講不完的,我會分成幾篇來為大家講述,形式主要以小實驗的方式來為大家講解。 ![資料](http://cdn.jayh.club/blog/20200909/100714602.png) > ❝ > 你好,我是`悟空哥`,**「7年專案開發經驗,全棧工程師,開發組長,超喜歡圖解程式設計底層原理」**。 我還`手寫了2個小程式`,Java刷題小程式,PMP刷題小程式,點選我的公眾號選單開啟! 另外有111本架構師資料以及1000道Java面試題,都整理成了PDF,可以關注公眾號 **「悟空聊架構」** 回覆 `悟空` 領取優質資料。 > ❞ **「轉發->在看->點贊->收藏->評論!!!」** 是對我最大的支援! ![二維碼](http://cdn.jayh.club/blog/20200909/1002175