Java8 JVM參數解讀

我們知道java虛擬機啓動時會帶有很多的啓動參數,Java命令本身就是一個多參數的啓動命令。那麼具體JVM啓動包含哪些參數呢?這篇文章針對java8的情況做一篇彙總解讀,包含大多數常見和不常見的命令參數,過於小衆的就不寫了。

命令參數包含

  • 標準參數(Standard Option)
  • 非標準參數(Non-Standard Options)
  • 高級運行時參數(Advanced Runtime Options)
  • 高級JIT編譯器參數(Advanced JIT Compiler Options)
  • 高級服務能力參數(Advanced Serviceability Options)
  • 高級垃圾回收參數(Advanced Garbage Collection Options)

java命令本身是通過下面的形式啓動java應用的。這是java的基礎,很多用慣了IDE的同學可能都不知道啓動命令了。

java [options] classname [args]
java [options] -jar filename [args]

這篇文章想總結的就是options這塊的內容。

具體解讀

標準參數(Standard Option)

標準參數是被所有JVM實現都要支持的參數。用於做一些常規的通用的動作,比如檢查版本、設置classpath等。

-agentlib:libname[=options]
這個命令加載指定的native agent庫。理論上這條option出現後,JVM會到本地固定路徑下LD_LIBRARY_PATH這裏加載名字爲libxxx.so的庫。而這樣的庫理論上是JVM TI的功能,具體可以參考JVM TI規範

-agentpath:pathname[=options]
這個參數指定了從哪個絕對路徑加載agent庫。與-agentlib相同,只不過是用絕對路徑來指明庫文件。

-client
-server
指定JVM的啓動模式是client模式還是server模式,具體就是 Java HotSpot Client(Server) VM 版本。目前64位的JDK啓動,一定是server模式,會忽略這個參數。

-Dproperty=value
這個參數是最常見的了,就是設置系統屬性,設置後的屬性可以在代碼中System.getProperty方法獲取到。

-d32 和 -d64
這個參數指定JVM啓動的環境模式,默認是32位啓動,如果系統不支持,那麼會報錯,-d64模式和-server模式是綁定的,也就是說-d64聲明瞭就默認是server模式。

disableassertions[:[packagename]...|:classname]
-da[:[packagename]...|:classname]
關閉指定包或類下的assertion,默認是關閉的。

-disablesystemassertions
-dsa
關閉系統包類下的assertion。

-enableassertions[:[packagename]...|:classname]
-ea[:[packagename]...|:classname]
同上,開啓指定包類下的assertion。

-enablesystemassertions
-esa
同上,開啓系統包類下的assertion。

-javaagent:jarpath[=options]
加載指定的java agent,具體需要傳入jar路徑。

-verbose:class
-verbose:gc
-verbose:jni
這些組合都是用來展示信息的,class展示的每個class的信息,gc展示每個GC事件的信息,jni開啓展示JNI調用信息。

-version
顯示版本信息,然後退出

非標準參數(Non-Standard Options)

這裏的非標準參數主要是針對官方JVM也就是HotSpot的,當然各家自研的JVM也有自己的非標準參數。

-X
著名的-X參數,就是一個help,展示所有-X開頭的參數說明。

-Xbatch
禁止後臺編譯。將編譯過程放到前臺任務執行。JVM默認會將編譯任務當做後臺任務執行。這個參數等價於-XX:-BackgroundCompilation

-Xfuture
強制class文件格式檢查。

-Xint
在 interpreted-only模式運行程序。編譯爲native的模式不再生效,所有的字節碼都在解釋器環境下解釋執行。

-Xinternalversion
打印一個更詳細的java版本信息,執行後退出。

-Xloggc:filename
設置gc日誌文件,gc相關信息會重定向到該文件。這個配置如果和-verbose:gc同時出現,會覆蓋-verbose:gc參數。

比如-Xloggc:/home/admin/logs/gc.log

-Xmaxjitcodesize=size
爲JIT編譯的代碼設置最大的code cache。默認的設置是240m,如果關閉了tiered compilation,那麼默認大小是48m。這個參數和-XX:ReservedCodeCacheSize是等價的。

-Xmixed
用解釋器執行所有的字節碼,除了被編譯爲native code的hot method。

-Xmnsize
設置初始最大的年輕代堆大小。

比如-Xmn256m

-Xmssize
設置初始的堆大小。

-Xmxsize
設置最大的內存分配大小。一般的服務端部署,-Xms和-Xmx設置爲同樣大小。與-XX:MaxHeapSize具有同樣的作用。具體設置參考[3]

-Xnoclassgc
關閉對class的GC。這樣設置可以節約一點GC的時間,不過帶來的影響就是class永駐內存,不當的使用會導致OOM風險。

-XshowSettings:category
查看settings信息,category可以是all、locale、properties和vm幾部分。

-Xsssize
設置thread stack大小,一般默認的幾個系統參數如下:

Linux/ARM (32-bit): 320 KB

Linux/i386 (32-bit): 320 KB

Linux/x64 (64-bit): 1024 KB

OS X (64-bit): 1024 KB

Oracle Solaris/i386 (32-bit): 320 KB

Oracle Solaris/x64 (64-bit): 1024 KB

-Xverify:mode
設置字節碼校驗器的模式,默認是remote,即只校驗那些不是通過bootstrap類加載器加載的字節碼。而還有一個模式還all,即全部都校驗。雖然還有一個模式是none,但是本質上jvm不生效這個參數。因爲字節碼校驗是非常重要的,如果關閉,將可能導致class文件格式就是錯的,這對於系統穩定和安全來說有重大風險。

高級運行時參數(Advanced Runtime Options)

這類參數控制Java HotSpot VM在運行時的行爲。

-XX:+DisableAttachMechanism
設置JVM的attach模式,如果啓動了這個參數,jvm將不允許attach,這樣類似jmap等程序就無法使用了。

-XX:ErrorFile=filename
當不可恢復的錯誤發生時,錯誤信息記錄到哪個文件。默認是在當前目錄的一個叫做hs_err_pid pid.log的文件。如果指定的目錄沒有寫權限,這時候文件會創建到/tmp目錄下。使用如下:

-XX:ErrorFile=/var/log/java/java_error.log

-XX:MaxDirectMemorySize=size
爲NIO的direct-buffer分配時指定最大的內存大小。默認是0,意思是JVM自動選擇direct-buffer的大小。使用如下:

-XX:MaxDirectMemorySize=1m

-XX:ObjectAlignmentInBytes=alignment
java對象的內存對齊大小。默認是8字節,JVM實際計算堆內存上限的方法是

4GB * ObjectAlignmentInBytes

-XX:OnError=string
在jvm出現錯誤(不可恢復)的時候,執行哪些命令。具體例子如下:

-XX:OnError="gcore %p;dbx - %p"

-XX:OnOutOfMemoryError=string
同上,具體錯誤是OOM。

-XX:-UseCompressedOops
禁止使用壓縮命令來壓縮指針引用。壓縮指針是默認開啓的,如果使用壓縮命令壓縮指針,可以在JVM內存小於32G時做到內存壓縮,即在64位機器上做到內存指針對齊只佔用32位而不是64位。這樣對於小於32G的JVM有非常高的性能提升。該參數只在64位JVM有效。

-XX:+UseLargePages
使用大頁內存[4],默認關閉,使用該參數後開啓。

高級JIT編譯器參數(Advanced JIT Compiler Options)

這部分的參數主要在動態just in time編譯時用到。

-XX:+BackgroundCompilation
後臺編譯,默認是開啓的,如果要關閉,使用-XX:-BackgroundCompilation或者-Xbatch

-XX:CICompilerCount=threads
編譯時的編譯器線程數。server版的JVM默認設置爲2,client版本默認設置爲1。如果tiered編譯開啓,則會伸縮到核數個線程。

XX:CodeCacheMinimumFreeSpace=size
編譯使用的最小空閒空間。默認是500KB,如果最小空閒空間不足,則編譯會停止。

-XX:CompileThreshold=invocations
編譯前解釋型方法調用次數。設置這個值,在編譯前,會用解釋器執行方法若干次用於收集信息,從而可以更高效率的進行編譯。默認這個值在JIT中是10000次。可以通過使用 -Xcomp參數來禁止編譯時的解釋執行。

-XX:+DoEscapeAnalysis
支持轉義分析,默認是開啓的。

-XX:InitialCodeCacheSize=size
初始化的code cache的大小,默認500KB。這個值應該不小於系統最小內存頁的大小。

-XX:+Inline
編譯時方法內聯。默認是開啓的。

-XX:InlineSmallCode=size
設置最大內聯方法的代碼長度,默認是1000字節,只有小於這個設置的方法纔會被編譯內聯。

-XX:+LogCompilation
編譯時日誌輸出,在編譯時會有一個hotspot.log的日誌輸出到當前工作目錄下。可以用-XX:LogFile指定不同的目錄。默認這個參數是關閉的,即編譯日誌不輸出。這個參數需要和-XX:UnlockDiagnosticVMOptions一起使用。也可以使用-XX:+PrintCompilation選項在控制檯打印編譯過程信息。

-XX:MaxInlineSize=size
編譯內聯的方法的最大byte code大小。默認是35,高於35個字節的字節碼不會被內聯。

-XX:+OptimizeStringConcat
字符串concat優化。默認開啓。

-XX:+PrintAssembly
通過使用外部的disassembler.so庫打印彙編的字節碼和native方法來輔助分析。默認是不開啓的,需要和-XX:UnlockDiagnosticVMOptions一起使用。

-XX:+PrintCompilation
將方法編譯過程打印到控制檯。默認不開啓。

-XX:+PrintInlining
將內聯方法打印出來。默認不開啓。

-XX:ReservedCodeCacheSize=size
設置爲了JIT編譯代碼的最大代碼cache大小。這個設置默認是240MB,如果關掉了tiered編譯,則大小是48MB。這個設置必須比初始化的-XX:InitialCodeCacheSize=size設置值大。

-XX:-TieredCompilation
關閉tiered編譯,默認是開啓的。只有Hotspot支持這個參數。

-XX:+UseCodeCacheFlushing
支持在關閉編譯器之前清除code cache。默認是開啓的,要關閉就把+換成-。

高級服務能力參數(Advanced Serviceability Options)

這部分參數可以做系統信息收集和擴展性的debug。

-XX:+ExtendedDTraceProbes
支持dtrace探測,默認是關閉的。

-XX:+HeapDumpOnOutOfMemory
設置當java.lang.OutOfMemoryError發生時,將heap內存dump到當前目錄的一個文件。默認是不開啓的。

-XX:HeapDumpPath=path
設置在dump heap時將文件dump到哪裏。默認是當前目錄下 java_pidpid.hprof這樣形式的文件。指定文件時例子如下:

-XX:HeapDumpPath=/var/log/java/java_heapdump.hprof

-XX:LogFile=path
指定日誌數據被記錄在哪裏,默認是在當前目錄的hotspot.log下。設置例子如下:

-XX:LogFile=/var/log/java/hotspot.log

-XX:+PrintClassHistogram
支持打印類實例的直方圖,在按下ctrl+c時(SIGTERM)觸發。默認是關閉的。等價於運行jmap -histo命令或者jcmd pid GC.class_histogram命令。

-XX:+PrintConcurrentLocks
支持打印java.util.concurrent的鎖信息,在SIGTERM時觸發。默認關閉,等價於運行jstack -l或者jcmd pid Thread.print -l命令。

-XX:+UnlockDiagnosticVMOptions
解鎖對JVM進行診斷的選項參數。默認是關閉的,開啓後支持一些特定參數對JVM進行診斷。

高級垃圾回收參數(Advanced Garbage Collection Options)

這部分參數控制JVM如何進行垃圾回收(GC)

-XX:+AggressiveHeap
java堆內存優化。默認是關閉的,如果開啓後,針對一些長時間運行的且有密集的內存分配操作,JVM根據系統cpu和內存的配置參數來進行優化。

-XX:+AlwaysPreTouch
支持在JVM啓動時touch每一頁,這樣做會導致每頁都會進入內存。可以用來模擬測試長時間運行的任務,將虛擬內存全部映射到物理內存。默認是關閉的。

-XX:+CMSClassUnloadingEnabled
支持CMS垃圾回收下的類卸載。默認是開啓的。

-XX:CMSExpAvgFactor=percent
設置一個時間百分比,用來加權併發回收統計的指數平均的樣本。默認是25%。

-XX:CMSInitiatingOccupancyFraction=percent
設置一個年老代的佔比,達到多少會觸發CMS回收。默認是-1,任何一個負值的設定都表示了用-XX:CMSTriggerRatio來做真實的初始化值。設置方法如下:

-XX:CMSInitiatingOccupancyFraction=20

-XX:+CMSScavengeBeforeRemark
開啓功能在CMSremark前進行Scavenge。默認是關閉的。

-XX:CMSTriggerRatio=percent
設置一個在CMS開始前的內存的觸發百分比,針對的是由-XX:MinHeapFreeRatio分配的內存。默認是80。

-XX:ConcGCThreads=threads
設置支持併發GC的線程數。默認值依賴於給JVM的CPU數目。設置方法如:

-XX:ConcGCThreads=2

-XX:+DisableExplicitGC
關閉顯式GC調用,即關閉System.gc()。默認是可以調用的。

-XX:+ExplicitGCInvokesConcurrent
支持通過System.gc()來做併發的GC。默認是不支持的。該參數一定要和-XX:+UseConcMarkSweepGC一起使用。

-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
支持通過System.gc()來做併發的GC並且卸載類。默認是不支持的。該參數一定要和-XX:+UseConcMarkSweepGC一起使用。

-XX:G1HeapRegionSize=size
設置在使用G1收集器時Java堆被劃分爲子區域的大小。在1MB到32MB之間,默認會根據Java堆的大小自動檢測。

-XX:+G1PrintHeapRegions
打印出哪些region是被分配的,哪些是被G1取回的。默認是關閉打印的。

-XX:G1ReservePercent=percent
設置一個堆內存的百分比用來作爲false ceiling,從而降低使用G1時晉升失敗的可能性。默認是10%。

-XX:InitialHeapSize=size
設置初始堆內存大小,需要設置爲0或者1024的倍數,設置爲0說明初始堆大小等於年輕代加年老代的大小。

-XX:InitialSurvivorRatio=ratio
設置初始的survivor空間佔比,當使用throughput型的GC時有效(即-XX:+UseParallelGC 或 -XX:+UseParallelOldGC)。運行過程中survivor空間佔比會自動根據應用運行調整,如果關閉了自適應調整策略(-XX:-UseAdaptiveSizePolicy),則XX:SurvivorRatio參數會成爲survivor空間佔比。計算survivor空間大小,依賴young的空間大小,計算公式如下

S=Y/(R+2)

其中Y是young空間大小,R是survivor空間佔比。一個例子就是如果young空間大小是2MB,而survivor默認佔比是8,那麼survivor的空間就是0.2MB。

-XX:InitiatingHeapOccupancyPercent=percent
設置一個觸發併發GC的堆佔用百分比。這個值對於基於整體內存的垃圾回收器有效,比如G1。默認是45%,如果設置爲0表示無停頓GC。

-XX:MaxGCPauseMillis=time
設置一個最大的GC停頓時間(毫秒),這是個軟目標,JVM會盡最大努力去實現它,默認沒有最大值設置。

-XX:MaxHeapSize=size
設置最大堆大小,這個值需要大於2MB,且是1024的整數倍。等價於-Xmx

-XX:MaxHeapFreeRatio=percent
設置在一次GC後最大的堆空閒空間佔比。如果空閒堆空間超過這個值,堆空間會被收縮。默認是70%。

-XX:MaxMetaspaceSize=size
爲類的元數據進行分配的metaspace最大native內存大小,默認情況這個值無限制。該值依賴於當前的JVM、其他在運行的JVM和系統可用內存。

-XX:MaxNewSize=size
設置最大的年輕代的堆大小。默認自動檢測。

-XX:MaxTenuringThreshold=threshold
設置在自適應GC大小的使用佔有最大閾值,默認對於parallel(throughput)的是15,對於CMS的是6。

-XX:MetaspaceSize=size
設置一個metaspace的大小,第一次超出該分配後會觸發GC。默認值依賴於平臺,該值會在運行時增加或減少。

-XX:MinHeapFreeRatio=percent
設置在一次GC後最小的空閒堆內存佔比。如果空閒堆內存小於該值,則堆內存擴展。默認是40%。

-XX:NewRatio=ratio
設置年輕代和年老代的比例,默認是2。

-XX:NewSize=size
設置初始的年輕代的大小。年輕代是分配新對象的地方,是 GC經常發生的地方。設置太低,會頻繁minor GC,設置太高的話就只會發生Full GC了。Oracle推薦設置爲整體內存的一半或者1/4。該參數等價於-Xmn。

-XX:ParallelGCThreads=threads
並行GC時的線程數。默認值是CPU數。

-XX:+ParallelRefProcEnabled
支持併發引用處理,默認是關閉的。

-XX:+PrintAdaptiveSizePolicy
打印自適應調整策略。默認關閉。

-XX:+PrintGC
打印每次GC的消息,默認是關閉的。

-XX:+PrintGCApplicationConcurrentTime
打印上次GC暫停到目前的時間。默認不打印。

-XX:+PrintGCApplicationStoppedTime
打印GC暫停的時間長度。默認不打印。

-XX:+PrintGCDateStamps
打印每個GC的日期時間戳。默認不打印。

-XX:+PrintGCDetails
打印每次GC的細節信息。默認不打印。

-XX:+PrintGCTaskTimeStamps
打印每個獨立的GC線程任務的時間戳。默認不打印。

-XX:+PrintGCTimeStamps
打印每次GC的時間戳。默認不打印。

-XX:+PrintStringDeduplicationStatistics
打印細節的deduplication信息。默認不打印。

-XX:+PrintTenuringDistribution
打印所在的年齡代的信息。具體例子如下:

Desired survivor size 48286924 bytes, new threshold 10 (max 10)

  • age 1: 28992024 bytes, 28992024 total
  • age 2: 1366864 bytes, 30358888 total
  • age 3: 1425912 bytes, 31784800 total
    ...

其中age1是最年輕的survivor,age2存活了2代,以此類推。默認該項關閉。

-XX:+ScavengeBeforeFullGC
在每次Full GC前做一次年輕代的GC。該項默認是開啓的。

-XX:SoftRefLRUPolicyMSPerMB=time
設置一個軟引用對象在上次被引用後在堆內存中保存的時間。默認是每1MB保存1秒鐘。該參數對於client模式和server模式有不同的動作,因爲client模式JVM在回收時會強制flush掉軟引用,然而server模式會嘗試先擴容堆空間。

-XX:StringDeduplicationAgeThreshold=threshold
string對象到達特定的age後會去除重複數據。默認是3,jvm中每次gc後存活的對象,age會加一。string對象在晉升爲年老代之前都是去除重複數據的候選對象。

-XX:SurvivorRatio=ratio
eden區和survivor區的比例。默認是8。

-XX:TargetSurvivorRatio=percent
設置在YGC後的期望的survivor空間佔比。默認是50%。

-XX:TLABSize=size
設置thread-local allocation buffer (TLAB)的初始化大小。

-XX:+UseAdaptiveSizePolicy
使用自適應分代大小。默認是開啓的。

-XX:+UseCMSInitiatingOccupancyOnly
設置使用佔用值作爲初始化CMS收集器的唯一條件。默認是不開啓。

-XX:+UseConcMarkSweepGC
設置讓CMS也支持老年代的回收。默認是不開啓的,如果開啓,那麼-XX:+UseParNewGC也會自動被設置。Java 8 不支持-XX:+UseConcMarkSweepGC -XX:-UseParNewGC這種組合。

-XX:+UseG1GC
設置使用G1作爲GC收集器。G1比較推薦在大堆應用場景下使用(大於6GB)。

-XX:+UseGCOverheadLimit
設置一種策略用來設置一個時間比率來限制在OOM之前的GC時間。默認是開啓的,並行GC時如果有多於98%以上的時間用來gc就會拋出OOM。當堆空間較小時這個參數有助於保護應用程序不至於長時間的停頓沒有進展。

-XX:+UseNUMA
使用NUMA[5]開啓性能優化。默認不開啓,該項只有在開啓了-XX:+UseParallelGC後纔有效。

-XX:+UseParallelGC
支持並行的垃圾收集器,即throughput垃圾收集。這可以在多核處理器下提升垃圾收集性能。默認不開啓,收集器由系統根據JVM和機器配置自動選擇。開啓後-XX:+UseParallelOldGC選項也自動開啓。

-XX:+UseParallelOldGC
支持FULL GC的並行收集器。默認不開啓。

-XX:+UseParNewGC
支持在年輕代用多線程進行垃圾收集。默認不開啓,使用-XX:+UseConcMarkSweepGC時會自動被開啓。

-XX:+UseSerialGC
支持使用串行收集器。默認不開啓。

-XX:+UseSHM
在Linux環境下支持JVM使用共享內存來設置大頁。

-XX:+UseStringDeduplication
支持string的去重存儲。默認關閉,要使用該選項,必須使用G1垃圾回收器-XX:+UseG1GC

-XX:+UseTLAB
在年輕代支持thread-local分配block,默認開啓。

引用

  1. java technotes
  2. jvm enhancement
  3. jvm gc tuning
  4. large pages
  5. NUMA
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章