秒懂JVM的三大引數型別,就靠這十個小實驗了
阿新 • • 發佈:2020-09-15
![封面](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