[翻译]Java -XX:+PrintFlagsFinal命令行参数详解
Contents
可能要翻墙…你懂的…
昨天在Google了一些与GC调优相关的资料后, 我无意中发现一些JVM标识是我从来没有见到过的.
-XX:+PrintFlagsFinal
所以,我尝试了一下我能想到的最简单的Java命令:
java -XX:+PrintFlagsFinal -version
我不打算贴出这条命令的输出结果, 因为它几乎有700多行. 除了打印标准版本的信息之外,它还可以打印一个几乎是你JDK构建的版本的所有JVM参数列表,它是一个拥有5列的表格, 这是我这篇文章所要讲解的.
Type | Name | Operator | Value | Application
来看单个参数的例子
java -XX:+PrintFlagsFinal -version | grep UseConcMarkSweepGC
bool UseConcMarkSweepGC := true {product}
你可以看到 boolean 标识, UseConcMarkSweepGC, 它的值被修改为 true 并且它适用于所有情况.
利用一些 *nix
魔术, 我们可以看到每一列的唯一的值
java -XX:+PrintFlagsFinal -version | awk '{if (NR!=1) {print $1}}' | sort | uniq
bool
ccstr
ccstrlist
double
int
intx
uint64_t
uintx
这些类型(type
列)是自解释的. 修改上面的命令中的$1
为$2
,你会获取所有可用的没带有想着元信息的标识名.
继续修改为$3
, 结果只有以下两行
:=
=
:=
意味着值是被修改的, =
表示默认值.
只获取唯一值的列表是没什么用的, 所以我会继续用一个特定的适用的参数. 由于空格是不规则的, 我们需要一个稍微不同的方式:
java -XX:+PrintFlagsFinal -version | awk -F '\\{' '{if(NR!=1) {print "\{"$2}}' | sort | uniq
{C1 pd product}
{C1 product}
{C2 diagnostic}
{C2 pd product}
{C2 product}
{lp64_product}
{manageable}
{pd product}
{product rw}
{product}
这些目录是由 复合标识符
来描述一个给定的标识符的适用情况.在进行一些深入挖掘后, 我在源码里发现它们的意思
product – 官方支持, JVM内部选项
rw – 可动态写入的.
C1 – Client JIT 编译器
C2 – Server JIT 编译器
pd – platform Dependent 平台独立
lp64 – 仅 64 位JVM
manageable – 外部定义的并且是可动态写入的.
diagnostic – 用于虚拟机debug的
experimental – 非官方支持的
有了这些新知识, 你可以开始看看client
与server
虚拟机的不同之处:
diff <(java -XX:+PrintFlagsFinal -server -version) <(java -XX:+PrintFlagsFinal -client -version)
< bool CMSCleanOnEnter = true {product}
> bool CMSCleanOnEnter = false {product}
< uintx ConcGCThreads = 0 {product}
> uintx ConcGCThreads = 2 {product}
< uintx InitialHeapSize := 268435456 {product}
> uintx InitialHeapSize = 0 {product}
< uintx MaxHeapSize := 4294967296 {product}
> uintx MaxHeapSize = 132120576 {product}
< uintx MaxNewSize = 18446744073709486080{product}
> uintx MaxNewSize := 174456832 {product}
< intx MaxTenuringThreshold = 15 {product}
> intx MaxTenuringThreshold := 4 {product}
< intx NewRatio = 2 {product}
< uintx NewSize = 1310720 {product}
> intx NewRatio := 7 {product}
> uintx NewSize := 21757952 {product}
< uintx OldPLABSize = 1024 {product}
> uintx OldPLABSize := 16 {product}
< uintx OldSize = 5439488 {product}
> uintx OldSize := 65404928 {product}
< bool ParGCUseLocalOverflow = false {product}
> bool ParGCUseLocalOverflow = true {product}
< uintx ParallelGCThreads := 8 {product}
> uintx ParallelGCThreads = 8 {product}
< bool UseAdaptiveSizePolicy = true {product}
> bool UseAdaptiveSizePolicy = false {product}
< bool UseConcMarkSweepGC = false {product}
> bool UseConcMarkSweepGC := true {product}
< bool UseParNewGC = false {product}
> bool UseParNewGC := true {product}
< bool UseParallelGC := true {product}
> bool UseParallelGC = false {product}
< uintx YoungPLABSize = 4096 {product}
> uintx YoungPLABSize = 1024 {product}
或者在我的例子里, 我可以看到当-XX:+AggressiveOpts
参数设置时,导致的参数更改. 这是在Google搜索时使我使用了这条途径:
diff <(java -XX:+PrintFlagsFinal -XX:+AggressiveOpts -version) <(java -XX:+PrintFlagsFinal -version) | grep ">\|<"
< bool AggressiveOpts := true {product}
> bool AggressiveOpts = false {product}
< intx AutoBoxCacheMax = 20000 {C2 product}
> intx AutoBoxCacheMax = 128 {C2 product}
< intx BiasedLockingStartupDelay = 500 {product}
> intx BiasedLockingStartupDelay = 4000 {product}
< bool EliminateAutoBox = true {C2 diagnostic}
> bool EliminateAutoBox = false {C2 diagnostic}
< bool OptimizeFill = true {C2 product}
< bool OptimizeStringConcat = true {C2 product}
> bool OptimizeFill = false {C2 product}
> bool OptimizeStringConcat = false {C2 product}
< bool UseFPUForSpilling = true {C2 product}
> bool UseFPUForSpilling = false {C2 product}
要切记的是 AggressiveOpts
参数在每一个Java的minor
(次)版本中都可能是不同的.
后记
以上的命令, 我自己也亲自运行了一次, 都是可以执行的. 实践才出真知, 不然翻译出来, 别人发现运行不了这些命令就不好了. 注意, 以上的命令是基于*nix
系统的.在我的Mac上的例子如下:
yangzhiyong@yangzhiyongdeMacBook-Pro:~
> diff <(java -XX:+PrintFlagsFinal -XX:+AggressiveOpts -version) <(java -XX:+PrintFlagsFinal -version) | grep ">\|<"
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
< bool AggressiveOpts := true {product}
> bool AggressiveOpts = false {product}
< intx AutoBoxCacheMax = 20000 {C2 product}
> intx AutoBoxCacheMax = 128 {C2 product}
< intx BiasedLockingStartupDelay = 500 {product}
> intx BiasedLockingStartupDelay = 4000 {product}
< bool UseFPUForSpilling = true {C2 product}
> bool UseFPUForSpilling = false {C2 product}
yangzhiyong@yangzhiyongdeMacBook-Pro:~
>
java -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal
:这条命令可以解放隐藏的参数。