Java HotSpot(TM) 64-Bit Server VM warning: NewSize (1536k) is greater than the MaxNewSize (1024k)

忘是亡心i 2022-10-07 01:56 121阅读 0赞

看<<实战java虚拟机>>书,运行一个demo,然后报了以下的错误提示。
Java HotSpot™ 64-Bit Server VM warning: NewSize (1536k) is greater than the MaxNewSize (1024k). A new max generation size of 1536k will be used.

测试代码为:

  1. package cn.shutdown.demo.jvm;
  2. /**
  3. * -Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails
  4. * @author dmn
  5. * @date 2021/6/15
  6. */
  7. public class NewSizeDemo {
  8. public static void main(String[] args) {
  9. byte[] b = null;
  10. for (int i = 0; i < 10; i++) {
  11. b = new byte[1 * 1024 * 1024];
  12. }
  13. }
  14. }

运行结果为:

  1. Java HotSpot(TM) 64-Bit Server VM warning: NewSize (1536k) is greater than the MaxNewSize (1024k). A new max generation size of 1536k will be used.
  2. [GC (Allocation Failure) [PSYoungGen: 512K->496K(1024K)] 512K->512K(19968K), 0.0015693 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
  3. Heap
  4. PSYoungGen total 1024K, used 738K [0x00000007bfe80000, 0x00000007c0000000, 0x00000007c0000000)
  5. eden space 512K, 47% used [0x00000007bfe80000,0x00000007bfebc8d0,0x00000007bff00000)
  6. from space 512K, 96% used [0x00000007bff00000,0x00000007bff7c010,0x00000007bff80000)
  7. to space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
  8. ParOldGen total 18944K, used 10256K [0x00000007bec00000, 0x00000007bfe80000, 0x00000007bfe80000)
  9. object space 18944K, 54% used [0x00000007bec00000,0x00000007bf6040a0,0x00000007bfe80000)
  10. Metaspace used 2700K, capacity 4486K, committed 4864K, reserved 1056768K
  11. class space used 289K, capacity 386K, committed 512K, reserved 1048576K

对这个警告提示很好奇,于是搜了搜,在StackOverflow里找到一个非常靠谱的答案。
JDK7 JVM different from JDK8

说明如下

The observed behaviour is related to some changes between Java 7 and Java 8.

这个情况与jdk7和jdk8中的变更有关

  1. -Xmn1024k

this option sets the initial and the maximum size of the heap for the young generation. It’s a shorthand for -XX:NewSize=1024k -XX:MaxNewSize=1024k.

这个jvm参数项设置 青年代堆内存的初始和最大的空间。是 -XX:NewSize=1024k -XX:MaxNewSize=1024k的简化写法

  1. // same command in Java 7/8
  2. java -XX:+PrintFlagsFinal -Xmn2048k -version | grep NewSize
  3. ...
  4. uintx MaxNewSize := 2097152
  5. uintx NewSize := 2097152
  6. ...

This behaviour seems to be not in line with the documentation.

这种行为似乎与文档不符。

Java 7

-Xmnsize or -XX:NewSize Sets the size of the young generation (nursery).

Java 8

The -XX:NewSize option is equivalent to -Xmn.

Because -XX:NewSize=2048k would set in Java7/8 only the initial size and the maximum size is chosen by the JVM.

因为 -XX:NewSize=2048k 会在 Java7/8 中设置只有初始大小,最大大小由 JVM 选择。

Hence if you specify -Xmn1024k it actually means you want to set

因此,如果你指定-Xmn1024k 意味着你想要设置如下

  1. -XX:NewSize=1024k -XX:MaxNewSize=1024k

In Java 7 (tested with 1.7.0_40-b43) the minimal size (for initial and maximum) is 196608. If you set the value to low. The start of the JVM fails with

在Java7中,(初始化和最大值)的范围的最小值为 196608,如果设置的值比这个值小,JVM虚拟机启动就会报下面的错误而失败。

  1. Error occurred during initialization of VM
  2. Too small new size specified

In Java 8 (tested with 1.8.0_74-b02) minimal size (for initial and maximum) is 1572864 (1536K).

在Java8中,(初始化和最大值)的范围的最小值为1572864 (1536K).

Now why you get this NewSize (1536k) is greater than the MaxNewSize (1024k) with Java 8.

所以java8中的,1536k是大于你设置的 -Xmn1m (-Xmn1024k) 的。

If you choose NewSize lower than the minimal size (1536K) it’s adjusted silently to that minimal size.

如果你选择的NewSize 初始化的值小于取值范围的最低值,那会自动被设置为最低值(1536k)

  1. java -XX:+PrintFlagsFinal -XX:NewSize=1k -version | grep NewSize
  2. ...
  3. uintx NewSize := 1572864
  4. ...

If you choose MaxNewSize lower than NewSizeMaxNewSize will be set silently to NewSize

如果 MaxNewSize的值小于 NewSizeMaxNewSize 的值会被自动设置为NewSize的值。

  1. java -XX:+PrintFlagsFinal -XX:NewSize=2048k -XX:MaxNewSize=1025k -version | \
  2. grep NewSize
  3. ...
  4. uintx MaxNewSize := 2097152
  5. uintx NewSize := 2097152
  6. ...

If you choose NewSize and MaxNewSize lower than minimal size and MaxNewSize bigger than NewSize, both are set to the minimal size.

NewSizeMaxNewSize 的值如果都低于最小值(1536k),则都会被设置为最小值(1536k)。

  1. java -XX:+PrintFlagsFinal -XX:NewSize=1024k -XX:MaxNewSize=1025k -version | \
  2. grep NewSize
  3. ...
  4. uintx MaxNewSize := 1572864
  5. uintx NewSize := 1572864
  6. ...
  7. java -XX:+PrintFlagsFinal -XX:NewSize=1 -XX:MaxNewSize=1025k -version | \
  8. grep NewSize
  9. ...
  10. uintx MaxNewSize := 1572864
  11. uintx NewSize := 1572864
  12. ...

But as soon you choose for MaxNewSize a value lower than 1025k equal to 1024k you get the error message you have discovered. Seems you found an edge case where a check is done before the adjustment.

但是,一旦您为“MaxNewSize”选择一个低于“1025k”的值,即等于“1024k”,您就会收到您发现的错误消息。你的这种情况正好是在在需要调整的界限边缘了。

  1. java -XX:NewSize=1 -XX:MaxNewSize=1025k -version
  2. java version "1.8.0_74"
  3. java -XX:NewSize=1 -XX:MaxNewSize=1024k -version
  4. Java HotSpot(TM) 64-Bit Server VM warning: NewSize (1536k) is greater than the \
  5. MaxNewSize (1024k). A new max generation size of 1536k will be used.

That’s explains why java -Xmn1025k -version runs fine where as java -Xmn1024k -version gives you the error message.

这就是为什么执行 java -Xmn1025k -version正常跑,但是 java -Xmn1024k -version 报错了。

After some more testing. The error seems to be printed only in case MaxNewSize is equal to 1024k. The next examples are working with the default size for NewSize and MaxNewSize.

经过测试,这个错误只会在 MaxNewSize的值为 1024k的时候进行输出。

  1. java -XX:NewSize=1 -XX:MaxNewSize=1023k -version
  2. java -XX:NewSize=1 -XX:MaxNewSize=1 -version

发表评论

表情:
评论列表 (有 0 条评论,121人围观)

还没有评论,来说两句吧...

相关阅读