使用的JDK版本为jdk1.7.0_79。
一、常用用法
1.1、常用用法1
1 | java [Options] class [Arguments] |
1.2、常用用法2
1 | java [Options] -jar file.jar [Arguments] |
二、含义
2.1、常用用法1含义
运行一个JVM进程,入口类为“class”(内含“public static void main(String[] args)”方法)。
2.2、常用用法2含义
运行一个JVM进程,入口类为“file.jar”指代的可执行JAR包内“MANIFEST.MF”文件中“Main-Class”参数配置的Java类(内含“public static void main(String[] args)”方法)。
三、选项
“Arguments”,表示传递给“public static void main(String[] args)”方法的参数。
接下来主要介绍“Options”,本文称其为“虚拟机参数”。
需要特别注意的是,关于“虚拟机参数”有两点不确定性:1)JVM进程支持的所有“虚拟机参数”和详细使用说明是不确定的(比如通过“-XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+AggressiveOpts -XX:+PrintFlagsFinal”虚拟机参数也只能获取到部分“-XX”类型虚拟机参数),除非查看OpenJDK源代码;2)“虚拟机参数”被传给JVM进程后,由于JVM进程存在缺省配置,“虚拟机参数”之间存在冲突(比如“-Xmn”和“-XX:NewRatio”)等因素,最终产生效果是不确定的,除非查看OpenJDK源代码。
即要想获得准确的关于“虚拟机参数”的信息,必须查看OpenJDK源代码。[3][4]
因此,接下来只介绍一些常见的“虚拟机参数”。
3.1、一般虚拟机参数
3.1.1、常用
描述见表1。
表1
名称 | 描述 |
---|---|
-classpath/-cp classpath | 配置用户自定义类路径 |
-Dproperty=value | 配置环境变量 |
-verbose/-verbose:class | 打印类加载日志 |
-verbose:gc | 打印GC简单日志 |
-verbose:jni | 打印本地方法使用日志 |
3.1.2、其他
描述见表2。
表2
名称 | 描述 |
---|---|
-client | 以“client”模式运行JVM进程 |
-server | 以“server”模式运行JVM进程 |
-d32 | 以32位模式运行JVM进程,需要本身支持才可,否则会报错 |
-d64 | 以64位模式运行JVM进程,需要本身支持才可,否则会报错 |
-agentlib:libname[=options] | 加载JVMTI实现库[5] |
-agentpath:pathname[=options] | 另外一种形式加载JVMTI实现库[5] |
-javaagent:jarpath[=options] | 加载Instrumentation机制代理程序包[6] |
-disableassertions/-da[:package name”…”|:class name] | 关闭assert语法 |
-enableassertions/-ea[:package name”…”|:class name] | 开启assert语法 |
-disablesystemassertions/-dsa | 关闭系统类中的assert语法 |
-enablesystemassertions/-esa | 开启系统类中的assert语法 |
-splash:imagepath | 运行JVM进程时,显示路径指定的图片 |
-help/-? | 打印帮助信息 |
-version | 显示JVM版本信息,退出 |
-showversion | 显示JVM版本信息,不退出 |
-version:release | 指定需要的JVM版本 |
-jre-restrict-search | 进行版本搜索时,包含私有JRE[7] |
-no-jre-restrict-search | 进行版本搜索时,不包含私有JRE[7] |
3.2、“-X”类型虚拟机参数
3.2.1、常用
描述见表3。
表3
名称 | 描述 |
---|---|
-Xloggc:file | 配置GC日志文件路径 |
-Xmn<SIZE> | 年轻代精确大小 |
-Xms<SIZE> | Java堆初始值和最小值 |
-Xmx<SIZE> | Java堆最大值 |
-Xss<SIZE> | Java虚拟机栈/本地方法栈的精确大小 |
3.2.2、其他
描述见表4。
表4
名称 | 描述 |
---|---|
-Xint | 对于字节码,使用解释器解释执行,而不使用编译器编译成汇编码或者机器码后执行[16] |
-Xcomp | 对于字节码,使用编译器编译成汇编码或者机器码后执行,而不使用解释器解释执行[16] |
-Xmixed | 默认方式。对于字节码,一般使用解释器解释执行;对于热点代码[17],使用编译器编译成汇编码或者机器码后执行[16] |
-Xbatch | 关闭后台编译机制 |
-Xbootclasspath:bootclasspath | 配置bootclasspath |
-Xbootclasspath/a:path | 在原有的bootclasspath后增加path |
-Xbootclasspath/p:path | 在原有的bootclasspath前增加path |
-Xcheck:jni | 对本地方法进行额外检查 |
-Xfuture | 对Class文件进行严格检查 |
-Xnoclassgc | 关闭对永久代的垃圾收集[8] |
-Xincgc | 等价于“-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode”,而“-XX:+CMSIncrementalMode”表示的“增量式并发收集模式”已经被声明废弃[9] |
-Xprof | 在标准输出中打印JVM进程一些指标统计值 |
-Xrs | 减少对操作系统信号量的使用 |
-Xverify:mode | 配置字节码校验模式 |
3.3、“-XX”类型虚拟机参数
“-XX”类型虚拟机参数具有如下格式:如果为布尔型,以“-XX:+/-name”形式进行开或关的配置;否则,以“-XX:name=value”形式进行值的配置。
3.3.1、常用
描述见表5。
表5
名称 | 描述 |
---|---|
-XX:MaxHeapSize=N | Java堆最大值,与“-Xmx<SIZE>”等价,两者具有相等优先级 |
-XX:NewSize=N | 配置年轻代的初始值和最小值 |
-XX:MaxNewSize=N | 配置年轻代最大值 |
-XX:PermSize=N | 设置永久代初始值和最小值 |
-XX:MaxPermSize=N | 设置永久代最大值 |
-XX:MaxDirectMemorySize=N | 设置“直接内存”最大值 |
-XX:SurvivorRatio=N | Eden区与Survivor区大小比值为N |
-XX:+/-UseSerialGC | 是否使用Serial+Serial Old收集器组合 |
-XX:+/-UseParNewGC | 是否使用ParNew+Serial Old收集器组合 |
-XX:+/-UseConcMarkSweepGC | 是否使用ParNew+CMS+Serial Old收集器组合,Serial Old垃圾收集器作为CMS收集器出现Concurrent Mode Failure失败后的后备收集器 |
-XX:+/-UseParallelGC | 是否使用Parallel Scavenge+Serial Old收集器组合 |
-XX:+/-UseParallelOldGC | 是否使用Parallel Scavenge+Parallel Old收集器组合 |
-XX:+/-UseG1GC | 是否使用G1收集器 |
-XX:ParallelGCThreads=N | 并行GC时,允许的最大线程数 |
-XX:PretenureSizeThreshold=N | 阈值,大于该值的对象直接在老年代分配 |
-XX:+/-HandlePromotionFailure | 是否允许“分配担保失败” |
-XX:MaxGCPauseMillis=N | 配置GC时最大停顿时间,收集器将尽量使得不超过该时间,仅在使用Parallel Scavenge收集器时生效 |
-XX:GCTimeRatio=N | 用户程序运行时间与GC时间比值为N,仅在使用Parallel Scavenge收集器时生效 |
-XX:+/-UseAdaptiveSizePolicy | 开启自动调节机制,不再需要手工指定新生代的大小,Eden区与Survivor区大小比值,晋升老年代对象年龄等细节参数 |
-XX:CMSInitiatingOccupancyFraction=N | 当老年代占用空间大于N%,则进行GC,仅在使用CMS收集器时生效 |
-XX:+/-UseCMSCompactAtFullCollection | 当进行Full GC时,进行内存碎片整理,仅在使用CMS收集器时生效 |
-XX:CMSFullGCsBeforeCompaction=N | 进行N次不进行整理的Full GC,然后执行1次带整理的Full GC,仅在使用CMS收集器时生效 |
-XX:+/-CMSClassUnloadingEnabled | 是否对永久代进行垃圾回收,仅在使用CMS收集器时生效 |
-XX:MaxTenuringThreshold=N | 阈值,当年轻代中对象年龄大于该值,则晋升到老年代 |
-XX:+/-CMSParallelRemarkEnabled | 是否允许CMS的重新标记阶段进行并行GC |
-XX:+/-UseCompressedOops | 64位JVM上是否压缩普通对象指针 |
-XX:+/-UseTLAB | 是否使用TLAB机制 |
-XX:+/-HeapDumpOnOutOfMemoryError | OutOfMemoryError发生时是否生成堆转存快照 |
-XX:+/-PrintTenuringDistribution | 打印GC日志时,打印Survivor区中对象年龄分布信息 |
-XX:+/-PrintGC | 是否打印GC简单日志,等价于“-verbose:gc” |
-XX:+/-PrintGCDetails | 是否打印GC详细日志 |
-XX:+/-PrintGCTimeStamps | 打印GC日志时,是否打印相对时间戳(自JVM进程启动以来经过多少秒) |
-XX:+/-PrintGCDateStamps | 打印GC日志时,是否打印绝对和相对时间戳 |
-XX:+/-PrintGCApplicationStoppedTime | 打印GC日志时,是否打印应用程序暂停了多少秒 |
-XX:+/-PrintGCApplicationConcurrentTime | 打印GC日志时,是否打印应用程序运行了多少秒 |
-XX:+/-TraceClassLoading | 是否打印类加载过程信息 |
-XX:+/-TraceClassUnLoading | 是否打印类卸载过程信息 |
-XX:+/-DisableExplicitGC | 是否忽略来自System.gc()方法触发的垃圾收集请求 |
-XX:MaxHeapFreeRatio=N | 当Xmx值比Xms值大时,Java堆可以动态收缩与扩展,这个参数控制当堆空闲大于指定比率时自动收缩 |
-XX:MinHeapFreeRatio=N | 当Xmx值比Xms值大时,Java堆可以动态收缩与扩展,这个参数控制当堆空闲小于指定比率时自动扩展 |
-XX:LargePageSizeInBytes=N | 使用指定大小的内存分页,需要操作系统的支持 |
-XX:+/-UseFastAccessorMethods | 当频繁反射执行某个方法时,生成字节码来加快反射的执行速度 |
3.3.2、其他
描述见表6。
表6
名称 | 描述 |
---|---|
-XX:+/-UseSpinning | 是否开启自旋锁避免线程频繁挂起和唤醒 |
-XX:PreBlockSpin=N | 使用自旋锁时默认的自旋次数 |
-XX:+/-UseThreadPriorities | 是否使用本地线程优先级 |
-XX:+/-UseBiasedLocking | 是否使用偏向锁 |
-XX:+/-AggressiveOpts | 是否使用激进的优化策略,需要根据具体应用特点进行分析,从而来判定采用该策略是否对性能有好处 |
-XX:+/-PrintConcurrentLocks | 是否打印J.U.C中锁的状态 |
-XX:OnOutOfMemoryError=”COMMAND” | 当抛出OutOfMemoryError异常时,执行指定的命令COMMAND |
-XX:OnError=”COMMAND” | 当抛出Error异常时,执行指定的命令COMMAND |
-XX:+/-DisableAttachMechanism | 是否关闭Dynamic Attach机制 |
四、补充
4.1、类路径
使用“java”命令尝试运行JVM进程时,类路径有3类:Bootstrap Classpath(默认值为“jre/lib”,可通过“-Xbootclasspath:bootclasspath”,“-Xbootclasspath/a:path”,“-Xbootclasspath/p:path”虚拟机参数更改),Extension Classpath(默认值为“jre/lib/ext”,没有途径更改),User Classpath(默认值为“.”,可通过“-classpath”,“-cp”虚拟机参数更改)。[10]
4.2、JVM运行模式client和server
自从JDK 5开始,当使用“java”命令尝试运行一个JVM进程时,JVM会判断一系列条件,当条件满足时,以server模式运行JVM进程,否则以client模式运行JVM进程,除非显式指定了“-client”或者“-server”。[11]
4.3、配置Java堆中年轻代大小参数[12][13][14]
配置Java堆中年轻代大小的参数有:-XX:NewRatio=N,-XX:NewSize=N,-XX:MaxNewSize=N,-Xmn<SIZE>。描述如表7。
表7
参数/参数组合 | 描述 |
---|---|
-XX:NewRatio=N | 老年代与年轻代大小比值为N,即年轻代与Java堆大小比值为1/N+1 |
-XX:NewSize=N,-XX:MaxNewSize=N | NewSize配置年轻代初始值和最小值,MaxNewSize配置年轻代最大值 |
-Xmn<SIZE> | -Xmn<SIZE>精确配置年轻代大小为SIZE |
以上3个“参数/参数组合”的优先级顺序为:“-Xmn<SIZE>” = “-XX:NewSize=N,-XX:MaxNewSize=N” > “-XX:NewRatio=N”,相等优先级情形下,位于后面的“参数/参数组合”覆盖前面而真正生效。接下来进行验证。
现有如下一段代码:
1 | public class Example { |
编译后,执行java -XX:NewRatio=4 -Xms10M -Xmx20M Example
命令,在该JVM进程(假设JVM进程ID为25101)还在运行时,执行jstat -gcnewcapacity 25101 1000 3
命令,得到如下所示结果:
1 | NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC |
再执行java -Xmn8M -XX:NewRatio=4 -Xms10M -Xmx20M Example
命令,在该JVM进程(假设JVM进程ID为25165)还在运行时,执行jstat -gcnewcapacity 25165 1000 3
命令,得到如下所示结果,结合上一个结果,得到“-Xmn<SIZE>”优先级 > “-XX:NewRatio=N”优先级结论:
1 | NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC |
再分别执行java -Xmn8M -XX:NewSize=4M -XX:MaxNewSize=7M -Xms10M -Xmx20M Example
和java -XX:NewSize=4M -XX:MaxNewSize=7M -Xmn8M -Xms10M -Xmx20M Example
命令,在JVM进程(假设JVM进程ID分别为25328和25369)还在运行时,分别执行jstat -gcnewcapacity 25328 1000 3
和jstat -gcnewcapacity 25369 1000 3
命令,得到如下两个所示结果,据此可得“-Xmn<SIZE>”优先级 = “-XX:NewSize=N,-XX:MaxNewSize=N”优先级结论:
1 | NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC |
综上,这3个“参数/参数组合”的优先级顺序已经得到验证。
4.4、常用虚拟机参数组合片段
接下来介绍一些常用虚拟机参数组合片段,需要注意的是,这些常用虚拟机参数组合片段只适用于一般情形,如果是特殊情形,还是需要进行针对性调优的。
4.4.1、打印GC日志
打印GC日志场景的常用虚拟机参数组合片段如下:
1 | -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -Xloggc:file |
4.4.2、服务器上运行JVM服务进程
服务器上运行JVM服务进程场景的常用虚拟机参数组合片段如下[15]:
1 | -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:NewSize=256m -XX:MaxNewSize=256m -Xms768m -Xmx768m -XX:MaxPermSize=128m -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseTLAB |
4.4.3、打印常见部分“-XX”类型虚拟机参数
打印常见部分“-XX”类型虚拟机参数(包括参数类型,名称,值等信息)场景的常用虚拟机参数组合片段如下[3][4]:
1 | -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+AggressiveOpts -XX:+PrintFlagsFinal |
参考文献: [1]http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/java.html [2]man java [3]http://www.javaworld.com/article/2073676/hotspot-jvm-options-displayed---xx--printflagsinitial-and--xx--printflagsfinal.html [4]http://q-redux.blogspot.hk/2011/01/inspecting-hotspot-jvm-options.html [5]https://www.ibm.com/developerworks/cn/java/j-lo-jpda2/ [6]https://www.ibm.com/developerworks/cn/java/j-lo-jse61/ [7]http://stackoverflow.com/questions/19510169/what-are-the-differences-between-private-jre-and-public-jre [8]http://stackoverflow.com/questions/27844418/java-xnoclassgc [9]https://news.ycombinator.com/item?id=3170354 [10]https://docs.oracle.com/javase/7/docs/technotes/tools/findingclasses.html [11]http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html [12]http://eyesmore.iteye.com/blog/1530996 [13]http://stackoverflow.com/questions/23880891/what-does-xmn-jvm-option-stands-for [14]https://gist.github.com/rednaxelafx/1066883 [15]https://docs.oracle.com/cd/E13209_01/wlcp/wlss30/configwlss/jvmgc.html [16]http://ifeve.com/useful-jvm-flags-part-1-jvm-types-and-compiler-modes-2 [17]http://www.importnew.com/20575.html