如果在META-INF/MANIFEST.MF
文件里面設置了Main-Class
屬性,那么你就可以很方便的通過java -classpath myapp.jar Main
命令甚至更簡潔的java -jar myapp.jar
命令,來啟動java虛擬機。這些命令會使用默認的設置來啟動JVM。
要想看到JVM執行時使用在使用哪些參數以及其各參數默認值,可以使用這個命令:
java -XX:+PrintFlagsFinal -version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
bool PrintHeapAtGC = false {product rw}
bool PrintHeapAtGCExtended = false {product rw}
...
uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product}
uintx AdaptiveSizePausePolicy = 0 {product}
...
bool UseCompressedOops := true {lp64_product}
...
bool UseXmmRegToRegMoveAll = true {ARCH product}
bool VMThreadHintNoPreempt = false {product}
intx VMThreadPriority = -1 {product}
intx VMThreadStackSize = 1024 {pd product}
intx ValueMapInitialSize = 11 {C1 product}
intx ValueMapMaxLoopSize = 8 {C1 product}
intx ValueSearchLimit = 1000 {C2 product}
bool VerifyMergedCPBytecodes = true {product}
...
|
如果這些參數還不夠全,你可以打開幾個開關:
java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version
大部分的參數都可以安全的看到默認值,但是某些參數需要在生產環境運行時來調整。
(后面花括號里面有product的表示可以在啟動參數中設置的,花括號里面是“product rw”的表示你還可以在jvm啟動后使用類似下面的命令來設置這些參數)
jinfo -flag -PrintHeapAtGC=true <pid>
基本的內存參數設置
對java應用而言,最基本的設置莫過於java堆大小的初始值和最大值設置了(一般認為生產環境初始值和最大值設置成一樣的比較合適)。
- -Xms<size> 設置java堆大小的初始值
- -Xmx<size> 設置java堆大小的最大值
如果你使用的java7或者更早版本的jdk,你可能發現“OutOfMemoryError: PermGen space”,這時你需要使用-XX:MaxPermSize=<size>參數來增大Perm區大小。server虛擬機默認的Perm區大小是64M,但很多應用所需的Perm區空間不止64M。
如果JVM虛擬機耗盡了堆空間,且GC垃圾回收不了時,會拋出“java.lang.OutOfMemoryError:Java heap space”,要分析內存占用情況,可以添加參數-XX:+HeapDumpOnOutOfMemoryError參數,這個參數會在拋出java.lang.OutOfMemoryError異常時,dump堆空間的數據到當前工作目錄下的一個文件中,-XX:HeapDumpPath=<path>可以指定這個dump文件的具體位置
垃圾回收(GC)
垃圾回收策略有很多,這里不細說,可以參考Java Garbage Collection Distilled。
不管你正在使用那一個垃圾收集器,你都可以用日志的方式記錄一段事件的垃圾回收的過程,來觀察垃圾回收的效果。你可以添加參數-verbose:gc來把垃圾回收日志輸出到標准輸出(STDOUT),但更好的方式是通過參數-Xloggc:<pathtofile>把垃圾回收日志輸出到指定的文件。
同時添加-XX:+PrintGCDateStamps參數可以記錄下垃圾回收的時間戳,添加-XX:+PrintGCDetails可以記錄下垃圾回收的事件細節。
默認情況下,垃圾回收日志文件不斷變大,但JVM還內置支持回轉日志文件(rotating the file),可搭配使用這三個參數:
-XX:+UseGCLogFileRotation 開啟回轉日志文件
-XX:GCLogFileSize=8K 設置單個文件最大的文件大小
-XX:NumberOfGCLogFiles=1 設置回轉日志文件的個數
最后,你可能需要使用-XX:+DisableExplicitGC參數來顯性的關閉手動GC功能(即調用jdk的建議GC的api:System.gc()),讓System.gc()方法變成一個空方法,讓垃圾回收托管給JVM的垃圾收集器。
實例
java -Xms10g -Xmx10g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/var/log/myapp/gc.log -XX:+UseGCLogFileRotation -XX:GCLogFileSize=10M -XX:NumberOfGCLogFiles=20 -jar myapp.jar
這個例子使虛擬機分配10GB內存和256MB給perm區(java7)。內存溢出時dump堆空間的共鞥啟動了,使用G1(garbage first)垃圾收集器,垃圾收集日志記錄到/var/log/myapp/gc.log中,同時開啟了日志文件回轉功能。
Referece
原創文章:【譯】JVM的默認參數,轉載請注明:轉載自戎碼一生