學習JVM參數(shù)前你需要了解些什么
JVM參數(shù)是什么
大家照相通常使用手機就夠用了,但是針對發(fā)燒友來說會使用更專業(yè)的設備,比如單反相機,在單反里有好幾個模式,P/A/S/M,其中P是傻瓜模式,程序會自動根據(jù)環(huán)境設置快門速度和光圈大小,以得到相對合適的曝光效果。A檔是光圈優(yōu)先,用戶可以自己設置光圈大小,快門速度等都交給相機程序來決定,類似半自動化的模式。S檔是快門優(yōu)先模式,和A檔類似,只是用戶可以設置快門速度。最后一個模式是M檔,這是純手動模式,由用戶自己來調整快門速度,光圈大小等,這個對人的要求就會很高,但是很多專家往往都會選擇M檔來拍攝自己的作品。
可以把JVM想象成相機,JVM參數(shù)想象成光圈大小,快門速度之類的參數(shù)值,這些參數(shù)對程序的運行會影響挺大。
java程序跑在JVM上,JVM會根據(jù)環(huán)境自動設置一些JVM參數(shù),但是這些參數(shù)并不能保證一定是最優(yōu)的,有些參數(shù)在啟動的時候就基本設置好了,它們在運行的時候還無法調整。為了讓JVM能更好地運行你的程序,還是有必要對JVM參數(shù)有一定的理解,知道這些JVM參數(shù)分別在什么場景下有效果,起到什么作用,比如我們到底期不期望類可以卸載,是否可以在運行的時候打印一些日志協(xié)助我們了解JVM的運行情況,出問題的時候是否可以自動給我們做一些現(xiàn)場數(shù)據(jù)的保留等,這些都是可以通過JVM參數(shù)來設置的。
JVM參數(shù)有多少
相機調整的無非就那么幾個參數(shù)值,那JVM參數(shù)到底有多少個呢,大概有1000多個,是不是讓你很震驚,沒錯,確實有這么多。
大家可以到 PerfMa社區(qū) 去看看所有這些JVM參數(shù)(注:這是PerfMa社區(qū)專門為大家分享JVM參數(shù)經驗的討論區(qū)),當然我們不一定非得對每個JVM參數(shù)要了解清楚,但是對一些常見的,有助于性能調優(yōu)的JVM參數(shù)還是有必要了解一下的。
JVM參數(shù)通常設置的位置
我們啟動一個java程序很簡單,命令類似如下
- java Main
 
我們都知道上面的Main是程序的啟動類,JVM執(zhí)行的時候會找到這個Main類里的如下簽名的函數(shù)
- Public static void main(String args[])
 
那這里函數(shù)的參數(shù)args怎么傳進來的呢?我們通過在啟動命令的主類后面加上相關的參數(shù),參數(shù)之間用空格分開,JVM會自動將這些參數(shù)作為args的組成部分傳進來,比如
- java Main arg1 arg2
 
這樣,args這個數(shù)組里自動會填充arg1和arg2兩個元素,這樣在你的程序里就可以使用這些參數(shù)了
我們把arg1和arg2這些叫做程序參數(shù),但是和我們課程相關的并不是程序參數(shù),而是JVM參數(shù),那JVM參數(shù)放到哪里呢?JVM參數(shù)都是放在主類之前,java命令之后,比如
- java -Xmx100M Main arg1 arg2
 
這里的-Xmx100M其實就是JVM參數(shù),所以所有的JVM參數(shù)都是放在這個位置的,如果不是這個位置,那你設置的JVM參數(shù)將會是無效的,如果參數(shù)出現(xiàn)不符合預期的情況,那請第一時間檢查的是你JVM參數(shù)設置的位置,當然還可能存在一些別的原因導致JVM參數(shù)和你設置的情況可能不一致的情況
JVM參數(shù)的寫法
那JVM參數(shù)具體怎么寫呢,可以有好幾種
- “-X” 開頭的,比如-Xmx100M
 - “-XX: ” 開頭的,比如-XX:+UseG1GC
 - “-” 開頭的,比如-verbose:gc
 
其中-X和-開頭的通常會被轉換為一個或者多個-XX:開頭的參數(shù),只是一個簡化的寫法,比如說-Xmx100M,JVM里會自動轉化為-XX:MaxHeapSize=100M,-verbose:class會自動轉換為-XX:+TraceClassLoading -XX:+TraceClassUnloading
通過Flags參數(shù)指定JVM參數(shù)文件
如果JVM參數(shù)都和源碼伴著一起發(fā)布的話,如果僅僅修改JVM參數(shù)也必須拉個分支提交代碼,這不是很友好,有什么好辦法呢?
我們可以在啟動參數(shù)里設置一個參數(shù)就好,這個參數(shù)類似如下
- java -XX:Flags=/home/admin/flags Main arg1 arg2
 
設置過這個參數(shù)之后,我們只要在服務的/home/admin目錄下創(chuàng)建flags文件,同時在這個文件里指定所有的JVM參數(shù)就可以了,但是對flags文件里的參數(shù)寫法會有些要求,-X之類的參數(shù)不能設置,但是可以用其等價的-XX的參數(shù)來替代,比如說-Xmx100M,只能用-XX:MaxHeapSize=100M來取代,同時在文件里不要出現(xiàn)-XX:,只要key=value或許+/-key就可以了,不同的參數(shù)之間用換行或者空格分開即可,比如flags文件的內容如下:
- MaxHeapSize=8G +UseG1GC
 
其實等價于
- -Xmx8G -XX:+UseG1GC
 
可以通過加上-XX:+PrintVMOptions可以打印設置過的JVM參數(shù)來驗證,比如
- java -XX:Flags=/home/admin/flags -XX:+PrintVMOptions Main arg1 arg2
 
通過VMOptionsFile參數(shù)來指定JVM參數(shù)文件
使用上面的Flags參數(shù)可能會比較別扭,因為設置參數(shù)和我們正常的寫法不太一樣,如果我們的JDK版本大于1.8的話,JVM提供了一個更人性化的參數(shù),那就是VMOptionsFile來取代Flags,這也是指定一個文件,這個文件里的JVM參的寫法和我們在java命令后寫的JVM參數(shù)寫法完全一樣
- java -XX:VMOptionsFile=/home/admin/flags Main arg1 arg2
 
在flags文件里我們可以這么寫
- -Xmx8G -XX:+UseG1GC
 
是不是方便了很多呢?
【本文是51CTO專欄作者李嘉鵬的原創(chuàng)文章,轉載請通過微信公眾號(你假笨,id:lovestblog)聯(lián)系作者本人獲取授權】
















 
 
 









 
 
 
 