- 我们需要知道的是找到默认值的方法,掌握默认值的大概量级,在不同的版本下哪些是常用的默认参数,哪些是必须设置的参数,哪些是可以选择的、尽量不要去碰的设置。
- 参数设置同一个类型会有多种参数,而且都有默认值,大家不要混用噢,混用的结果很多时候难以预料,虽然在某种情况下可能得到了一个测试结果,但如果你没有真正了解JVM的内核源码,是不可能知道所有细节的,即测试结果不能当成任何场景下的一个结论,只能作为一种参考。
本篇文章基于Java 6(update 21oder 21之后)版本, HotSpot JVM 提供给了两个新的参数,在JVM启动后,在命令行中可以输出所有XX参数和值。
- -XX:+PrintFlagsFinal and -XX:+PrintFlagsInitial
让我们现在就了解一下新参数的输出。以 -client 作为参数的 -XX:+PrintFlagsFinal
的结果是一个按字母排序的590个参数表格(注意,每个release版本参数的数量会不一样)
- $ java -client -XX:+PrintFlagsFinal Benchmark
- [Global flags]
- uintx AdaptivePermSizeWeight = 20 {product}
- uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
- uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product}
- uintx AdaptiveSizePausePolicy = 0 {product}[...]
- uintx YoungGenerationSizeSupplementDecay = 8 {product}
- uintx YoungPLABSize = 4096 {product}
- bool ZeroTLAB = false {product}
- intx hashCode = 0 {product}
(校对注:你可以尝试在命令行输入上面的命令,亲自实现下)
表格的每一行包括五列,来表示一个XX参数。第一列表示参数的数据类型,第二列是名称,第四列为值,第五列是参数的类别。第三列”=”表示第四列是参数的默认值,而”:=” 表明了参数被用户或者JVM赋值了。
注意对于这个例子我只是用了Benchmark类,因为这个系列前面的章节也是用的这个类。甚至没有一个主类的情况下你能得到相同的输出,通过运行Java 带另外的参数 -version.现在让我们检查下 server VM提供了多少个参数。我们也能指定参数-XX:+UnlockExperimentalVMOptions
和-XX:+UnlockDiagnosticVMOptions ;来解锁任何额外的隐藏参数。
- $ java -server -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal Benchmark
724个参数,让我们看一眼那些已经被赋值的参数。- $ java -server -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal Benchmark | grep ":"
- uintx InitialHeapSize := 57505088 {product}
- uintx MaxHeapSize := 920649728 {product}
- uintx ParallelGCThreads := 4 {product}
- bool PrintFlagsFinal := true {product}
- bool UseParallelGC := true {product}
(校对注:这个命令非常有用)我们仅设置一个自己的参数 -XX:+PrintFlagsFinal。其他参数通过server VM基于系统设置的,以便以合适的堆大小和GC设置运行。
如果我们只想看下所有XX参数的默认值,能够用一个相关的参数,-XX:+PrintFlagsInitial 。 用 -XX:+PrintFlagsInitial
, 只是展示了第三列为“=”的数据(也包括那些被设置其他值的参数)。
然而,注意当与-XX:+PrintFlagsFinal 对比的时候,一些参数会丢失,大概因为这些参数是动态创建的。
研究表格的内容是很有意思的,通过比较client和server VM的行为,很明显了解哪些参数会影响其他的参数。有兴趣的读者,可以看一下这篇不错文章Inspecting HotSpot JVM Options。这个文章主要解释了第五列的参数类别。
-XX:+PrintCommandLineFlags
让我们看下另外一个参数,事实上这个参数非常有用: -XX:+PrintCommandLineFlags
。这个参数让JVM打印出那些已经被用户或者JVM设置过的详细的XX参数的名称和值。
换句话说,它列举出 -XX:+PrintFlagsFinal的结果中第三列有":="的参数。以这种方式,
我们可以用-XX:+PrintCommandLineFlags作为快捷方式来查看修改过的参数。看下面的例子。
- $ java -server -XX:+PrintCommandLineFlags Benchmark
- -XX:InitialHeapSize=57505088 -XX:MaxHeapSize=920081408 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+UseParallelGC
现在如果我们每次启动java 程序的时候设置 -XX:+PrintCommandLineFlags 并且输出到日志文件上,这样会记录下我们设置的JVM 参数对应用程序性能的影响。类似于 -showversion(见 Part1),我建议 –XX:+PrintCommandLineFlags 这个参数应该总是设置在JVM启动的配置项里。因为你从不知道你什么时候会需要这些信息。
奇怪的是在这个例子中,通过 -XX:+PrintCommandLineFlags 列出
堆的最大值会比通过-XX:+PrintFlagsFinal列举出的相应值小一点。如果谁知道两者之间不同的原因,请告诉我。
转载自:http://ifeve.com/useful-jvm-flags-part-3-printing-all-xx-flags-and-their-values/
Java程序员有时候需要了解JVM相关的参数,不管是出于好奇或者工作需要。Oracle的文档中列出了一些,(点击这里),单并不是全部,而且有些参数的设置会默认启用或者关闭其他一些参数,而在某些情况下设置某个参数是不会生效的。还有些时候你想让JVM做某些事情,但是你不知道那个参数可以用。下面介绍一些办法用以列出所有参数,这样你在研究或者Google的时候也比较有明确的目标。
如果你想查看一下线上正在运行的JVM到底设置了那些参数,生效的是那些,可能用到的方法:
1. 在Linux下用ps命令找到启动Java应用时的参数
- ps -ef | grep "your java app name"
这个命令会打出你启动Java应用时传给java命令的所有参数,你可以看到里面的JVM参数。
2.直接看启动脚本,或者参数配置
你未必能找到所有设置这JVM参数的地方,容易遗漏。
一般来讲以上两种办法都需要对JVM了如指掌或者非常熟悉,至少对特定的参数。
其实JVM中有一个参数-XX:+PrintFlagsFinal,可以打印出几乎所有的JVM支持的参数以及他们的默认值。如果你想要查看你的Java应用到底使用了那些参数,只要在启动的时候加上这个参数就可以了。
1.查看你使用的JDK支持的参数
- java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
2.打印Java应用启用的JVM参数- java -XX:+PrintFlagsFinal -classpath=/path/to/your/libs MainClass
3.如果你的Java应用已经是运行状态了,你想查看某个JVM参数生效没有可以使用jinfo这个工具。比如说大名鼎鼎的G1垃圾回收器,在JDK7update3中不论是客户端(-client)还是服务器(-server)模式下都不是默认启动的。
jinfo是随JDK一起发布的,使用时先用jps找到Java应用的pid。直接运行jinfo可以查看使用说明。
- jinfo -flag UseParallelOldGC 31072
3.如果你的Java应用已经是运行状态了,你想查看某个JVM参数生效没有可以使用jinfo这个工具。比如说大名鼎鼎的G1垃圾回收器,在JDK7update3中不论是客户端(-client)还是服务器(-server)模式下都不是默认启动的。
jinfo是随JDK一起发布的,使用时先用jps找到Java应用的pid。直接运行jinfo可以查看使用说明。
- jinfo -flag UseParallelOldGC 31072 <span style="color: rgb(0, 204, 0); line-height: 18px; font-family: Consolas, 'Courier New', Courier, mono, serif; background-color: inherit;"> </span>
JDK中实用的工具还很多,可以逐个的体验一下${JAVA_HOME}/bin目录中的每个命令,有惊喜。
参考:http://blog.csdn.net/redhat456/article/details/7360249