原文出处

可能要翻墙…你懂的…


昨天在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 – 非官方支持的

有了这些新知识, 你可以开始看看clientserver虚拟机的不同之处:

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:这条命令可以解放隐藏的参数。