0%

java命令

使用的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
2
3
4
5
public class Example {
public static void main(String[] args) throws InterruptedException {
Thread.sleep(10 * 60 * 1000L);
}
}

编译后,执行java -XX:NewRatio=4 -Xms10M -Xmx20M Example命令,在该JVM进程(假设JVM进程ID为25101)还在运行时,执行jstat -gcnewcapacity 25101 1000 3命令,得到如下所示结果:

1
2
3
4
NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
2048.0 4096.0 2048.0 384.0 192.0 384.0 192.0 3328.0 1664.0 0 0
2048.0 4096.0 2048.0 384.0 192.0 384.0 192.0 3328.0 1664.0 0 0
2048.0 4096.0 2048.0 384.0 192.0 384.0 192.0 3328.0 1664.0 0 0

再执行java -Xmn8M -XX:NewRatio=4 -Xms10M -Xmx20M Example命令,在该JVM进程(假设JVM进程ID为25165)还在运行时,执行jstat -gcnewcapacity 25165 1000 3命令,得到如下所示结果,结合上一个结果,得到“-Xmn<SIZE>”优先级 > “-XX:NewRatio=N”优先级结论:

1
2
3
4
NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
8192.0 8192.0 8192.0 768.0 768.0 768.0 768.0 6656.0 6656.0 0 0
8192.0 8192.0 8192.0 768.0 768.0 768.0 768.0 6656.0 6656.0 0 0
8192.0 8192.0 8192.0 768.0 768.0 768.0 768.0 6656.0 6656.0 0 0

再分别执行java -Xmn8M -XX:NewSize=4M -XX:MaxNewSize=7M -Xms10M -Xmx20M Examplejava -XX:NewSize=4M -XX:MaxNewSize=7M -Xmn8M -Xms10M -Xmx20M Example命令,在JVM进程(假设JVM进程ID分别为25328和25369)还在运行时,分别执行jstat -gcnewcapacity 25328 1000 3jstat -gcnewcapacity 25369 1000 3命令,得到如下两个所示结果,据此可得“-Xmn<SIZE>”优先级 = “-XX:NewSize=N,-XX:MaxNewSize=N”优先级结论:

1
2
3
4
5
6
7
8
9
10
11
NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
4096.0 7168.0 4096.0 704.0 384.0 704.0 384.0 5760.0 3328.0 0 0
4096.0 7168.0 4096.0 704.0 384.0 704.0 384.0 5760.0 3328.0 0 0
4096.0 7168.0 4096.0 704.0 384.0 704.0 384.0 5760.0 3328.0 0 0

---分割线---

NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
8192.0 8192.0 8192.0 768.0 768.0 768.0 768.0 6656.0 6656.0 0 0
8192.0 8192.0 8192.0 768.0 768.0 768.0 768.0 6656.0 6656.0 0 0
8192.0 8192.0 8192.0 768.0 768.0 768.0 768.0 6656.0 6656.0 0 0

综上,这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
您的支持将鼓励我继续分享!