JAVA命令行工具(一)--JAVA
1.总述
java
命令用来启动一个JAVA应用。有以下两种用法:
java [options] mainclass [args...]
java [options] -jar jarfile [args...]
第一种从指定JAVA类启动,第二种从可运行jar包启动。启动过程有三步,首先启动JAVA运行时环境JRE,然后加载所需的类,最后调用类的main()
方法。正确的main()
方法形式如下:
public static void main(String[] args)
注意:该方法必须声明为public
和static
,且必须返回void
。方法的参数必须为字符串数组,其中第一个元素为main()
方法所在类包含包路径的全名(?)。
命令行各部分的含义如下:
options
由空格分隔的命令行选项,下一节详细说明。
mainclass
待启动类包含包路径的类全名,其中需要含有main()
方法。
jarfile
待启动jar包的路径,其中需要manifest
文件指明含有main()
方法的启动类。
args
传给启动类main()
方法的参数,由空格分隔。
2.命令行选项
java的命令行选项分为三类:
- 标准选项。JVM必须实现的选项,实现通用的功能,比如:检查JRE的版本,设置类路径等。
- 扩展选项。HotSpot实现常用功能的选项,其他JVM不一定实现。此类选项前缀为
-X
。 - 高级选项。高级选项是开发者选项,不保证在所有JVM上被实现,并可能会改变。有以下四种类型:
- 高级运行时选项:控制JVM运行时行为。
- 高级维护性选项:支持收集系统信息和调试。
- 高级GC选项:控制JVM的垃圾收集行为。
- 高级JIT选项:控制JVM的及时编译行为。
设置选项值时,如果值为布尔Boolean
型,表示开启或关闭某一功能。使用加号+
表示开启某一功能,减号-
表示关闭某一功能。示例如下:
-XX:+OptionName -XX:-OptionaName
如果选项需要参数,可在选项之后跟随参数或使用特定分隔符隔开。常见的分隔方式有:空白字符分隔、冒号:
分隔和等号分隔=
。一些示例如下:
-Xmx2G // 不分隔
-cp a.jar // 空白字符分隔
-agentlib:foo // 冒号分隔
-XX:ThreadStackSize=size // 等号分隔
如果参数值表示字节大小,可以直接使用整数或使用一些后缀,如g
和G
、m
和M
、k
和K
。2GB的字节可以使用如下表示:
2G 2048m 2097152K 2147483648
了解了这些,下面开始介绍一些重要的选项。
3.标准选项
-version
打印版本信息然后退出。经常使用该选项来查看JAVA的版本或验证java命令是否可用。与之相似的另一个选项为:-showversion,区别在于:-showversion打印版本信息后不会退出。
--class-path classpath, -classpath classpath , or -cp classpath
指定JAVA搜寻类的类路径,会覆盖CLASSPATH
环境变量的值。类路径为指定符号分隔(linux为冒号:
,windows为分号;
)的目录、jar包路径或zip包路径,用来指定搜索class
文件的路径。其详细说明可查看ClassPath详解。
-Dproperty=value
指定一个系统属性值。属性和属性值都为字符形式,其中属性名不能含有空白字符,属性值如果需要空白字符,需要使用双引号"
包裹。一个正确的示例如下:
-Dfoo="foo bar"
该值可以在JAVA程序中使用如下代码获取:
System.getProperty("foo")
-server -client
指定JVM的模式,client模式用于桌面应用,server模式用于服务端应用。JVM对两种模式有相应优化,client模式加载速度较快,可以快速启动;server模式加载速度较慢但运行起来较快。
-agentlib:libname[=options]
加载指定native代理库。可以指定多个库,各个库名之间使用逗号,
分隔。不同操作系统下的加载方式稍有不用,如下的选项:
-agentlib:foo
- Linux环境下,将在系统变量
LD_LIBRARY_PATH
指定的路径下尝试加载名为libfoo.so
的库。 - Windows环境下,将在系统变量
PATH
指定的路径下尝试加载名为foo.dll
的库。
一个经常使用的示例如下:
-agentlib:jdwp=transport=dt_socket,server=y,address=8000
该选项将加载JAVA调试协议库JDWP
,使用socket在端口8000上进行监听并会在加载主类前挂起JVM。
-agentpath:pathname[=options]
该选项与-agentlib
等效,区别在于路径需指定为代理库或文件的全路径名。
-javaagent:jarpath[=options]
加载指定的Java语言代理。
-verbose:[class|gc|jni]
启用详细输出。
- class:展示每个加载类的详细信息。
- gc:展示每个垃圾收集(GC)事件的详细信息。
- jin:展示每个原生方法和原生接口(JNI)活动的详细信息。
4.扩展选项
-Xmx size
指定堆的最大大小。指定2GB的最大堆,可用如下的任意方式:
-Xmx2G -Xmx2048m -Xmx2097152K -Xmx2147483648
该选项mx可用英文单词meomory maximum
助记, 此外,该选项等效于-XX:MaxHeapSize
。
-Xms size
指定堆的初始化大小。指定1GB的初始堆,可用如下的任意方式:
-Xms1g -Xms1024M -Xms1048576k -Xms1073741824
对于server端应用,建议将-Xmx
和-Xms
设置为相同的值,如此能使server端应用有较好的性能。如果不设置该值,那么该值将默认设置为老年代和新生代大小的和。该选项ms可用英文单词memory startup
助记。
-Xmn size
指定堆中新生代的初始化和最大大小。指定256MB的新生代,可用如下的任意方式:
-Xmn256m -Xmn262144k -Xmn268435456
如果将新生代的值设置过大,那么一次新生代GC的时间就会过长;如果将新生代的值设置过小,又会引起频繁新生代GC。官方建议该值设置在堆最大值的25%-50%区间内。该选项mn可用英文单词memory new/nursery
助记,此外也可用选项-XX:NewSize
和-XX:MaxNewSize
设置新生代的初始化和最大大小。
-Xss size
指定线程栈的大小。指定1MB的栈大小,可用如下的任意方式:
-Xss1m -Xss1024k -Xss1048576
该选项的默认值随操作系统不同而不同:Linux环境下默认为1MB,Windows环境则取决于虚拟内存的大小。该选项ss可用英文单词stack size
助记,此外该选项等效于-XX:ThreadStackSize
。
-Xloggc:option
启用JVM统一日志框架,将带时间戳的GC状态记录到文件中。
-Xlog:option
配置或者启用JVM统一日志框架。JDK9 引入。
-Xbootclasspath/a:directories| zip|JAR files
额外添加指定路径、jar包或zip包到默认启动类路径。指定多个路径或多个文件时,在Linux下使用冒号:
分隔,在Windows下使用分号;
分隔。
-Xbatch
关闭后台编译。默认情况下,JVM在后台编译,编译完成前方法在解释模式下运行。-Xbatch
选项关闭后台编译,方法需要在编译完成后运行。该选项等效于-XX:-BackgroundCompilation
。
-Xcomp
当方法第一次被调用时强制进行编译。默认情况下,client模式的方法将会在解释模式下运行1000次(server模式下10000次),以便编译器收集信息用于编译优化。如果指定该选项,将关闭解释模式而强制使用编译模式。该选项的初衷用于提升代码执行效率,但不建议开启,因为收集信息后的编译优化的性能好于强制编译。更多的解释可参考这个链接。
如果希望改变解释模式的执行次数,可使用选项-XX:CompileThreshold
。
-Xint
使用解释模式运行程序。该种模式下,不会享受即时编译JIT带来的性能提升。
-Xmixed
同时使用解释模式和编译模式运行程序。对于字节码中多次调用的热点方法,JVM会将其编译为本地代码以便提高执行效率;而调用次数较少的方法则使用解释模式执行,从而减少编译和优化成本。默认情况下,JVM使用该模式。
-Xnoclassgc
关闭对Class
对象的垃圾收集。该选项的初衷是减少GC时间,从而减少应用的停顿时间。设置该选项后,Class
对象将永久存活,不进行GC。设置该选项时需要足够小心,否则容易产生OOM。
-Xshare:[auto|on|off]
设置类数据共享(class data sharing-CDS)模式。
- auto:尽可能使用CDS。HotSpot 32-Bit VM的默认值。
- on:必须使用CDS。如果不能使用将打印出错信息并退出。
- off:关闭CDS。
-XshowSettings:[all|locale|properties|vm]
打印设置信息并继续运行JAVA应用。其中all打印全部种类的设置信息,是该选项的默认值。
-Xfuture
开启严格的类文件格式检查、强制遵守类文件格式规范。当开发者开发新代码时应启用该选项,该选项在未来版本可能会设置为默认开启。
-Xverify:[remote|all|none]
设置字节码的验证方式。由于字节码验证可以保证类文件符合JVM规范,从而提高安全性,所以不要关闭验证。各个模式的说明如下:
- remote。验证除Bootstrap class之外的其他类,该模式为默认值。
- all。所有字节码都需要验证。
- none。关闭字节码验证。
5.高级运行时选项
-XX:MaxHeapSize=size
设置最大堆大小,见-Xmx
。
-XX:InitialHeapSize=size
设置初始堆大小,见-Xms
。
-XX:NewSize
设置新生代初始大小,见-Xmn
。
-XX:MaxNewSize=size
设置新生代最大大小,见-Xmn
。
-XX:ThreadStackSize=size
设置线程栈大小,见-Xss
。
-XX:MaxMetaspaceSize=size
设置永久代大小,JDK8以下使用-XX:MaxPermSize=size
。
-XX:MaxDirectMemorySize=size
设置Java Nio可以使用的最大直接内存。默认情况下,该选项值为0,JVM将会自主确定一个大小值。
-XX:-UseCompressedOops
关闭对象指针压缩。默认情况下,该选项开启,当Java堆小于32GB时将使用对象指针压缩,此时对象指针将使用32位,而不是64位。当Java堆小于32GB时可以提高性能。该选项只用于64位架构的JVM。
-XX:ObjectAlignmentInBytes=alignment
设置Java对象在内存存储时的对齐字节数。该选项的默认值是8个字节,注意该选项为全局配置,不能单独为某个对象指定对齐字节数。该值需要为2的次数,该值的取值范围为[8,256]。随着该值的增加,那么对象间的空隙字节也将增大,将抵消由UseCompressedOops
压缩对象指针带来的好处。
-XX:-CompactStrings
关闭字符串压缩功能。该选项为JDK9引入,之前,Java的字符串统一使用UTF-16编码,每个字符都编码为双字节。JDK9默认开启该选项,只包含单字节字符的字符串将使用ISO-8859-1或Latin-1编码,编码后只占1个字节,节省50%的空间;包含至少一个多字节字符的字符串仍然使用UTF-16编码。
-XX:-UseBiasedLocking
关闭偏向锁。大量使用无争用锁的应用关闭偏向锁将获得显著的性能提升,但其他模式的锁会降低性能。
-XX:+UseGCLogRotation
对大日志文件进行分页,必须已指定选项-Xloggc:filename
。有两种分页方式:
- -XX:NumberOfGClogFiles=lineNumber:按指定行数分割日志文件。
- -XX:GCLogFileSize=number:按文件大小分割日志文件,默认值为512K。
-XX:+UseContainerSupport
该选项支持JVM自动检测容器支持。启用该选项后,运行在docker 容器中的JVM会自动确定Java进程可用的CPU数量和内存大小。该选项仅在x64架构的Linux环境可用,默认开启,可使用-XX:-UseContainerSupport
关闭。
-XX:ActiveProcessorCount=xx
覆盖用于计算线程池大小的CPU核心数。一般情况下,JVM会自主确定操作系统可用的CPU核心数。该选项对于在docker容器中运行的Java进程十分有用,可以隔离CPU资源。该选项在关闭UseContainerSupport
时依然有效。
-XX:+DisableAttachMechanism
关闭工具关联JVM的功能。默认情况下,该选项开启,此时可以使用诊断工具如:jcmd,jstack,jmap和jinfo。
-XX:+UnlockCommercialFeatures
开启一些商业特性。这些特性可查看这个链接。
6.高级可维护性选项
-XX:+HeapDumpOnOutOfMemoryError
开启堆转储功能。当Java应用抛出OutOfMemoryError
异常时可以使用堆转储工具(HPROF)将Java堆存储到文件中。默认文件存储在当前路径下,文件名为java_pid[pid].hprof。此外,还可使用选项-XX:HeapDumpPath=path
指定文件地址。一个示例如下(其中%p表示进程PID):
-XX:HeapDumpPath=/data/log/java_pid%p.hprof
-XX:OnOutOfMemoryError=string
设置发生OutOfMemoryError
后执行的处理命令,多个命令可使用分号;
分隔。如果命令中含有空格,需要使用双引号"
包裹命令。
-XX:ErrorFile=filename
指定Java进程发生不可恢复的错误时,保存错误文件的地址和文件名。默认情况下,错误文件存储在当前路径下,文件名为hs_err_pid[pid].log。一个示例如下:
-XX:ErrorFile=/data/log/java_error_%p.log
如果文件由于权限问题、硬盘已满或是其他问题而不能在指定目录下创建,那么该文件将创建在临时目录下。对于Linux环境,临时目录为/tmp;对于Windows环境,临时目录由环境变量TMP
指定,如果该环境变量没有指定,那么将使用TEMP
环境变量的值。
-XX:OnError=string
指定Java进程发生不可恢复的错误后执行的处理命令,与选项-XX:ErrorFile
类似。Linux环境下发生错误时,可使用gcore
命令创建core文件,并启动一个debugger用于调试错误,示例如下:
-XX:OnError="gcore %p;dbx - %p"
-XX:LogFile=path
设置日志文件的地址。默认情况下,文件被写到当前目录下,文件名为hotspot.log。一个示例如下:
-XX:LogFile=/data/log/hotspot.log
附: 本文取材的Java Tool Reference。