java應用監測(2)-java命令的祕密

tags: java, troubleshooting, monitorhtml


一句話歸納:簡單的java啓動命令,原來藏着這麼多祕密,本文爲你揭曉。java

1 引言

剛開始學java的同窗,必定都不會忘記安裝完jdk後,都會使用java -version命令來檢測一下是否安裝成功,那還有沒有其它參數可使用呢?平時開發和運行java應用時,常常看到一些-D的參數(如使用maven時,package時會使用-Dmaven.test.skip),這些參數是用來作什麼的?還有常常說到調優,都會涉及到-Xms-Xmx的設置,它是什麼意思呢?這些,基本都是在使用java命令啓動應用時所使用的參數,它的參數有不少,特別涉及到應用調優和問題診斷時會常用,學習java的同窗都應該瞭解一下。本文將對java命令的啓動參數進行詳細描述,着重講解經常使用的設置及用於調試監測的設置。linux

2 java應用啓動

啓動java應用使用的是java(class文件)或java -jar(jar或war包)命令,java命令其實就是生成一個JVM的實例,java應用則運行於此JVM實例中,JVM負責類加載,運行時區域堆棧分配等工做,當應用退出,JVM實例也會關閉。啓動多個java應用,也會啓動多個JVM實例,它們不會相互影響(但它們都共享同一系統的資源),這也是爲何使用一個JDK,能夠跑多個java應用的背後邏輯。使用java命令啓動應用所使用的參數,基本是用於JVM的,JVM實例經過調用某個初始類的main()方法來運行一個Java程序,此方法將做爲該程序初始線程的起點,任何其餘的線程都是由這個初始線程啓動的。在JVM內部有兩種線程:守護線程(如垃圾回收線程)和非守護線程(main方法線程及用戶使用Thread建立的線程),當該程序中全部的非守護線程都終止時,JVM實例將自動退出。程序員

3 java應用啓動參數說明

java命令究竟有哪些參數能夠用,這些參數分別有什麼做用,簡單的不帶參數使用javajava -helpjava -?,便可看到此命令的使用方法及參數描述,以下所示:算法

java執行類文件,java -jar執行jarwar文件。上面只是把參數簡要的列了出來,更詳細的參數說明,可參考官網的java命令說明https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html)。使用java命令啓動應用所使用的參數,基本是用於JVM的,某種程度上也叫作JVM參數。總的來講,java啓動參數共分爲三大類,分別是:shell

  • 標準參數(-):相對穩定的參數,每一個版本的JVM均可用。
  • 非標準X參數(-X):默認jvm實現這些參數的功能,可是並不保證全部jvm實現都知足,且不保證向後兼容。
  • XX參數(-XX):此類參數各個jvm實現會有所不一樣,未來可能會隨時取消。

下面將會對這些參數進行說明。編程

3.1 標準參數(-)

從前面使用java -?能夠看到,以-開頭的參數,都屬於標準參數,咱們經常使用的-help-version-classpath-Dproperty=value等均屬於標準參數。參數詳細說明以下:bootstrap

-d32及-d64  分別表示應用運行在32位或64位的環境中,使用Java HotSpot Server VM的默認使用的是server模式,而server模式默認使用的是-d64,所以在沒有使用此參數時,默認就是-d64。

-server       選擇 "server" VM,默認 VM 是 server,表示是在服務器類計算機上運行。

-cp或-classpath <目錄和 zip/jar 文件的類搜索路徑>linux用":",windows用";"來分隔目錄, JAR 檔案和 ZIP 檔案列表, 用於搜索類文件。
      使用-classpath後jvm將再也不使用CLASSPATH中的類搜索路徑,若是-classpath和CLASSPATH都沒有設置,則jvm使用當前路徑(.)做爲類搜索路徑。

-D<名稱>=<值> 設置系統屬性,運行在此jvm之上的應用程序可用System.getProperty(「property」)獲得value的值。
      若是value中有空格,則須要用雙引號將該值括起來,如-Dfoo=」foo bar」。該參數一般用於設置系統級全局變量值,如配置文件路徑,以便該屬性在程序中任何地方均可訪問。

-verbose:[class|gc|jni] 啓用詳細輸出,通常在調試和診斷時,都會把gc的詳細信息輸出
-version      輸出產品版本並退出
-version:<值> 須要指定的版本才能運行
-showversion  輸出產品版本並繼續,即輸出版本後,繼續按java執行,這是跟-version的區別
-jre-restrict-search | -no-jre-restrict-search 在版本搜索中包括/排除用戶專用 JRE
-? -help      輸出此幫助消息
-X            輸出非標準選項的幫助
-ea或-enableassertions [:<packagename>...|:<classname>] 按指定的粒度啓用斷言,默認jvm關閉斷言機制
-da或-disableassertions [:<packagename>...|:<classname>] 禁用具備指定粒度的斷言
-esa | -enablesystemassertions 啓用系統斷言
-dsa | -disablesystemassertions 禁用系統斷言
-agentlib:<libname>[=<選項>] 加載本機代理庫 <libname>, 例如 -agentlib:hprof
                  另請參閱 -agentlib:jdwp=help 和 -agentlib:hprof=help
-agentpath:<pathname>[=<選項>] 按完整路徑名加載本機代理庫
-javaagent:<jarpath>[=<選項>] 加載Java編程語言代理, 請參閱 java.lang.instrument
-splash:<imagepath> 使用指定的圖像顯示啓動屏幕,通常用於圖形編程。
複製代碼

由上面描述可,可知道咱們經常使用的-version-classpath-Dproperty=value是用於作什麼的了。特別提一下-classpath(之前遇到因爲這個致使運行問題),jvm在加載類時,搜索的路徑就是此路徑,而它在linux及windows使用的分隔符是不同的,linux用:,windows用;來分隔。windows

3.2 非標準X參數(-X)

使用命令java -X,便可把非標準參數輸出,平時使用中,咱們用得較多的就是-Xloggc-Xms<size>,-Xmx<size>,-Xss<size>,-Xmn<size>了,詳細說明以下所示:性能優化

-Xmixed  默認是mixed,使用它們來設置JVM的本地代碼編譯模式
-Xint    表示解釋執行,全部的字節碼將被直接執行,而不會編譯成本地碼
-Xcomp   表示第一次使用就編譯成本地代碼。
-Xbatch  禁止後臺代碼編譯,強制在前臺編譯,編譯完成以後才能進行代碼執行,默認狀況下,jvm在後臺進行編譯,若沒有編譯完成,則前臺運行代碼時以解釋模式運行
-Xbootclasspath:    設置搜索路徑以引導類和資源,讓jvm從指定路徑(能夠是分號分隔的目錄、jar、或者zip)中加載bootclass,用來替換jdk的rt.jar
-Xbootclasspath/a:  附加在引導類路徑末尾
-Xbootclasspath/p:  置於引導類路徑以前,讓jvm優先於bootstrap默認路徑加載指定路徑的全部文件
-Xcheck:jni    對JNI函數進行附加check;此時jvm將校驗傳遞給JNI函數參數的合法性,在本地代碼中遇到非法數據時,jmv將報一個致命錯誤而終止;使用該參數後將形成性能降低,請慎用。
-Xfuture   讓jvm對類文件執行嚴格的格式檢查(默認jvm不進行嚴格格式檢查),以符合類文件格式規範,推薦開發人員使用該參數
-Xincgc    開啓增量gc(默認爲關閉);這有助於減小長時間GC時應用程序出現的停頓;但因爲可能和應用程序併發執行,因此會下降CPU對應用的處理能力
-Xloggc:file   與-verbose:gc功能相似,只是將每次GC事件的相關狀況記錄到一個文件中,文件的位置最好在本地,以免網絡的潛在問題。若與verbose命令同時出如今命令行中,則以-Xloggc爲準。
-Xms   指定jvm堆的初始大小,默認爲物理內存的1/64,最小爲1M;能夠指定單位,好比k、m,若不指定,則默認爲字節。
-Xmx   指定jvm堆的最大值,默認爲物理內存的1/4或者1G,最小爲2M;單位與-Xms一致。
-Xss   設置單個線程棧的大小,通常默認爲512k。
-Xmn   設置堆(heap)的年輕代的初始值及最大值,單位與-Xms一致,年輕代是存儲新對象的地址,也是GC發生得最頻繁的地方,若設置太小,則會容易觸發年輕代垃圾回收(minor gc),若設置過大,只觸發full gc,則佔用時間會很長,oracle建議是把年輕代設置在堆大小的四份之一到一半的。這命令同時設置了初始值和最大值,可使用-XX:NewSize和-XX:MaxNewSiz來分別設置。
-XshowSettings    顯示全部設置並繼續
複製代碼

上述參數中,-Xms<size>,-Xmx<size>,-Xss<size>,-Xmn<size>都是咱們性能優化中很重要的參數,-Xloggc是在沒有專業跟蹤工具狀況下排錯的好手。

3.3 XX參數(-XX)

此類參數很是豐富,包括高級運行時參數,高級JIT編譯參數,高級維護參數和高級GC參數,在官網能夠看到它所有的參數(https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html),各個版本jvm實現有可能會有所不一樣。其中按設置格式,主要分爲兩類,一種是boolean類型,主要用於功能開關,一種是key-value類型,主要性能、調試參數等設置,下面列舉一些主要使用的參數。

3.3.1 boolean類型

此類參數,格式:-XX:[+-]<name>,做爲功能開關,表示啓用或者禁用屬性。如下列舉一些:

-XX:+PrintFlagsFinal  輸出參數的最終值
-XX:+PrintFlagsInitial 輸出參數的默認值
-XX:-DisableExplicitGC  禁止調用System.gc();但jvm的gc仍然有效
-XX:+MaxFDLimit 最大化文件描述符的數量限制
-XX:+ScavengeBeforeFullGC   新生代GC優先於Full GC執行
-XX:+UseGCOverheadLimit 在拋出OOM以前限制jvm耗費在GC上的時間比例
-XX:-UseConcMarkSweepGC 對老生代採用併發標記交換算法進行GC
-XX:-UseParallelGC  啓用並行GC
-XX:-UseParallelOldGC   對Full GC啓用並行,當-XX:-UseParallelGC啓用時該項自動啓用
-XX:-UseSerialGC    啓用串行GC
-XX:+UseThreadPriorities    啓用本地線程優先級
-XX:-UseG1GC    啓用G1的GC
複製代碼

3.3.2 key-value類型

此類參數,格式:-XX:<name>=<value>表示屬性name的值爲value。在性能調優和調試監測時,會常常用到。

  • 性能調優

性能調優時,主要是對JVM的內存分配狀況的調優,包括堆大小,年輕代大小,年輕年老代比例等等。

-XX:LargePageSizeInBytes=4m 設置用於Java堆的大頁面尺寸
-XX:MaxHeapFreeRatio=70 GC後java堆中空閒量佔的最大比例
-XX:MaxNewSize=size 新生成對象能佔用內存的最大值
-XX:MaxPermSize=64m 老生代對象能佔用內存的最大值
-XX:MinHeapFreeRatio=40 GC後java堆中空閒量佔的最小比例
-XX:NewRatio=2  新生代內存容量與老生代內存容量的比例
-XX:NewSize=2.125m  新生代對象生成時佔用內存的默認值
-XX:ReservedCodeCacheSize=32m   保留代碼佔用的內存容量
-XX:ThreadStackSize=512 設置線程棧大小,若爲0則使用系統默認值
-XX:+UseLargePages  使用大頁面內存
複製代碼
  • 調試監測

在須要對應用進行監測,特別是觀察GC狀況,OOM後檢查問題等。

-XX:-CITime 打印消耗在JIT編譯的時間
-XX:ErrorFile=./hs_err_pid<pid>.log 保存錯誤日誌或者數據到文件中
-XX:-ExtendedDTraceProbes   開啓solaris特有的dtrace探針
-XX:HeapDumpPath=./java_pid<pid>.hprof  指定導出堆信息時的路徑或文件名
-XX:-HeapDumpOnOutOfMemoryError 當首次遭遇OOM時導出此時堆中相關信息
-XX:OnError="<cmd args>;<cmd args>" 出現致命ERROR以後運行自定義命令
-XX:OnOutOfMemoryError="<cmd args>;<cmd args>"  當首次遭遇OOM時執行自定義命令
-XX:-PrintClassHistogram    遇到Ctrl-Break後打印類實例的柱狀信息,與jmap -histo功能相同
-XX:-PrintConcurrentLocks   遇到Ctrl-Break後打印併發鎖的相關信息,與jstack -l功能相同
-XX:-PrintCommandLineFlags  打印在命令行中出現過的標記
-XX:-PrintCompilation   當一個方法被編譯時打印相關信息
-XX:-PrintGC    每次GC時打印相關信息
-XX:-PrintGC Details    每次GC時打印詳細信息
-XX:-PrintGCTimeStamps  打印每次GC的時間戳
-XX:-TraceClassLoading  跟蹤類的加載信息
-XX:-TraceClassLoadingPreorder  跟蹤被引用到的全部類的加載信息
-XX:-TraceClassResolution   跟蹤常量池
-XX:-TraceClassUnloading    跟蹤類的卸載信息
-XX:-TraceLoaderConstraints 跟蹤類加載器約束的相關信息
複製代碼

4 經常使用java應用啓動參數

通過前面幾個章節的介紹,你們應該對java的啓動參數(JVM參數)有必定的瞭解,但參數太多了,不可能把全部參數都得記住,有須要時,建議你們看-help或者看官網說明來查閱。不少時候,咱們只須要記住幾個經常使用的便可。下面總結一下經常使用的JVM參數。

4.1 經常使用標準參數

  • -version,場景:想查看JDK版本,java -version
  • -D<名稱>=<值>,場景:maven跳過單元測試,使用java -Dmaven.test.skip=true,
  • -cp或-classpath, 場景:設置須要加載的jar包位置,使用java -cp lib/test.jar com.test.TestMain
  • -verbose:gc, 場景:輸出GC詳細信息

4.2 經常使用X參數

  • -Xms<size>-Xmx<size>,場景:因爲內存不足發生oom,調大堆大小,如設置爲1G,能夠java -Xms1024m -Xmx1024m,一般爲了不頻繁發生GC,-Xms-Xmx設置爲一致。
  • -Xss<size>,場景:線程操做數及局部變量多,把線程棧的大小調大,能夠java -Xss1024k
  • -Xmn<size>,場景:年輕代大小設置爲512m,能夠java -Xmn512m
  • -Xloggc:file,場景:將每次GC事件的相關狀況記錄到一個文件中以便於後續分析,能夠java -Xloggc:logs/gc.log

4.3 經常使用XX參數

打印GC相關的內容,包括堆狀況,GC詳情,GC時間,發生OOM時,生成快照,發生錯誤是記錄錯誤日誌等,以下:

  • -XX:+PrintHeapAtGC
  • -XX:+PrintGCDetails
  • -XX:+PrintGCDateStamps
  • -XX:+PrintGCTimeStamps
  • -XX:+PrintTenuringDistribution
  • -XX:+PrintGCApplicationStoppedTime
  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeapDumpPath=logs/heapdump.hprof,發生OOM時,dump出快照到文件heapdump.hprof中。
  • -XX:ErrorFile=logs/java_error_%p.log,發生JVM錯誤時,把日誌輸出到java_error_%p.log中。

以上參數均是使用度很高的參數,在使用java命令啓動應用時,能夠把這些參數加上,以便於後續調優與問題診斷。

5 總結

簡單的java啓動命令,使用起來原來這麼複雜,固然通常來講,只使用javajava -jar來按默認值啓動應用,也不會有太大問題。只是涉及到調優、監測、診斷時,瞭解這些參數,無疑是高級程序員必要的技能。但願經過本文,你們對java命令及參數能夠作到心中有數。

參考資料

相關閱讀

相關文章
相關標籤/搜索