最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Has the semantics of NewRatio in JVM changed despite the Oracle docs stating otherwise? - Stack Overflow

programmeradmin3浏览0评论

The Oracle docs say (emphasis mine):

For example, setting -XX:NewRatio=3 means that the ratio between the young and old generation is 1:3. In other words, the combined size of the eden and survivor spaces will be one-fourth of the total heap size.

The same was said here: What is the meaning of the -XX:NewRatio and -XX:OldSize JVM flags?

Thus, higher ratio makes Old Gen larger than Young Gen, not the opposite. However when checking on Java 17 with java -XX:MaxHeapSize=100M -XX:+PrintFlagsFinal -version, I see that MaxNewSize (Young Gen) gets 2/3 of the MaxHeapSize making it larger than Old Gen which is the opposite of what the docs say:

java -XX:MaxHeapSize=100M -XX:+PrintFlagsFinal -version | grep -E "MaxHeapSize|MaxNewSize|NewRatio"
   size_t MaxHeapSize                              = 104857600                                 {product} {command line}
   size_t MaxNewSize                               = 62914560                                  {product} {ergonomic}
    uintx NewRatio                                 = 2                                         {product} {default}
   size_t SoftMaxHeapSize                          = 104857600                              {manageable} {ergonomic}

openjdk version "17.0.2" 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)

Then I run the same command with Java 8 and get values aligned with the docs and common knowledge that I keep seeing on the Internet:

java -Xmx100M -XX:+PrintFlagsFinal -version | grep -E "MaxHeapSize|MaxNewSize|NewRatio"
    uintx MaxHeapSize                              := 109051904                           {product}
    uintx MaxNewSize                               := 36175872                            {product}
    uintx NewRatio                                  = 2                                   {product}
openjdk version "1.8.0_392"
OpenJDK Runtime Environment Corretto-8.392.08.1 (build 1.8.0_392-b08)
OpenJDK 64-Bit Server VM Corretto-8.392.08.1 (build 25.392-b08, mixed mode)

So, despite MaxHeapSize=100M and default NewRatio=2 in both cases, MaxNewSize is 62914560 in Java 17 and 36175872 in Java 8.

My question: what is happening? Is it a bug or has something changed but not reflected in the docs? Will appreciate any guidance to the right direction

EDIT: found out that if I specify NewRatio=2 explicitly, then Java 17 prints the expected result similar to Java 8:

java -XX:MaxHeapSize=100M -XX:NewRatio=2 -XX:+PrintFlagsFinal -version | grep -E "MaxHeapSize|MaxNewSize|NewRatio"
   size_t MaxHeapSize                              = 104857600                                 {product} {command line}
   size_t MaxNewSize                               = 34603008                                  {product} {ergonomic}
    uintx NewRatio                                 = 2                                         {product} {command line}
   size_t SoftMaxHeapSize                          = 104857600                              {manageable} {ergonomic}
openjdk version "17.0.2" 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)

Is this a bug or something with ergonomics that affects the values?

The Oracle docs say (emphasis mine):

For example, setting -XX:NewRatio=3 means that the ratio between the young and old generation is 1:3. In other words, the combined size of the eden and survivor spaces will be one-fourth of the total heap size.

The same was said here: What is the meaning of the -XX:NewRatio and -XX:OldSize JVM flags?

Thus, higher ratio makes Old Gen larger than Young Gen, not the opposite. However when checking on Java 17 with java -XX:MaxHeapSize=100M -XX:+PrintFlagsFinal -version, I see that MaxNewSize (Young Gen) gets 2/3 of the MaxHeapSize making it larger than Old Gen which is the opposite of what the docs say:

java -XX:MaxHeapSize=100M -XX:+PrintFlagsFinal -version | grep -E "MaxHeapSize|MaxNewSize|NewRatio"
   size_t MaxHeapSize                              = 104857600                                 {product} {command line}
   size_t MaxNewSize                               = 62914560                                  {product} {ergonomic}
    uintx NewRatio                                 = 2                                         {product} {default}
   size_t SoftMaxHeapSize                          = 104857600                              {manageable} {ergonomic}

openjdk version "17.0.2" 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)

Then I run the same command with Java 8 and get values aligned with the docs and common knowledge that I keep seeing on the Internet:

java -Xmx100M -XX:+PrintFlagsFinal -version | grep -E "MaxHeapSize|MaxNewSize|NewRatio"
    uintx MaxHeapSize                              := 109051904                           {product}
    uintx MaxNewSize                               := 36175872                            {product}
    uintx NewRatio                                  = 2                                   {product}
openjdk version "1.8.0_392"
OpenJDK Runtime Environment Corretto-8.392.08.1 (build 1.8.0_392-b08)
OpenJDK 64-Bit Server VM Corretto-8.392.08.1 (build 25.392-b08, mixed mode)

So, despite MaxHeapSize=100M and default NewRatio=2 in both cases, MaxNewSize is 62914560 in Java 17 and 36175872 in Java 8.

My question: what is happening? Is it a bug or has something changed but not reflected in the docs? Will appreciate any guidance to the right direction

EDIT: found out that if I specify NewRatio=2 explicitly, then Java 17 prints the expected result similar to Java 8:

java -XX:MaxHeapSize=100M -XX:NewRatio=2 -XX:+PrintFlagsFinal -version | grep -E "MaxHeapSize|MaxNewSize|NewRatio"
   size_t MaxHeapSize                              = 104857600                                 {product} {command line}
   size_t MaxNewSize                               = 34603008                                  {product} {ergonomic}
    uintx NewRatio                                 = 2                                         {product} {command line}
   size_t SoftMaxHeapSize                          = 104857600                              {manageable} {ergonomic}
openjdk version "17.0.2" 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)

Is this a bug or something with ergonomics that affects the values?

Share Improve this question edited Feb 15 at 16:45 Turkhan Badalov asked Feb 15 at 15:58 Turkhan BadalovTurkhan Badalov 9241 gold badge11 silver badges19 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

You've missed the fact that JDK 17 defaults to G1 GC, whereas JDK 8 selects Parallel GC by default. If you set -XX:+UseG1GC or -XX:+UseParallelGC explicitly, the behavior will be the same both on JDK 8 and JDK 17.

Different GC algorithms indeed have different generation sizing policy. G1 uses adaptive sizing by default and it does not take NewRatio into account unless the flag is set explicitly. Note that JVM has too many GC tunables, some of which contradict others. Generally, JVM favors flags that are set on the command line.

发布评论

评论列表(0)

  1. 暂无评论