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

看<<实战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.

测试代码为:

package cn.shutdown.demo.jvm;

/**
 * -Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails
 * @author dmn
 * @date 2021/6/15
 */
public class NewSizeDemo {
    public static void main(String[] args) {
        byte[] b = null;
        for (int i = 0; i < 10; i++) {
            b = new byte[1 * 1024 * 1024];
        }
    }
}

运行结果为:

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.
[GC (Allocation Failure) [PSYoungGen: 512K->496K(1024K)] 512K->512K(19968K), 0.0015693 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 1024K, used 738K [0x00000007bfe80000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 512K, 47% used [0x00000007bfe80000,0x00000007bfebc8d0,0x00000007bff00000)
  from space 512K, 96% used [0x00000007bff00000,0x00000007bff7c010,0x00000007bff80000)
  to   space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
 ParOldGen       total 18944K, used 10256K [0x00000007bec00000, 0x00000007bfe80000, 0x00000007bfe80000)
  object space 18944K, 54% used [0x00000007bec00000,0x00000007bf6040a0,0x00000007bfe80000)
 Metaspace       used 2700K, capacity 4486K, committed 4864K, reserved 1056768K
  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中的变更有关

-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的简化写法

// same command in Java 7/8
java -XX:+PrintFlagsFinal -Xmn2048k -version | grep NewSize
...
uintx MaxNewSize                               := 2097152
uintx NewSize                                  := 2097152
...

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 意味着你想要设置如下

-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虚拟机启动就会报下面的错误而失败。

Error occurred during initialization of VM
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)

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

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

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

java -XX:+PrintFlagsFinal -XX:NewSize=2048k -XX:MaxNewSize=1025k -version | \
    grep NewSize
...
uintx MaxNewSize                               := 2097152
uintx NewSize                                  := 2097152
...

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)。

java -XX:+PrintFlagsFinal -XX:NewSize=1024k -XX:MaxNewSize=1025k -version | \
    grep NewSize
...
uintx MaxNewSize                               := 1572864
uintx NewSize                                  := 1572864
...
java -XX:+PrintFlagsFinal -XX:NewSize=1 -XX:MaxNewSize=1025k -version | \
    grep NewSize
...
uintx MaxNewSize                               := 1572864
uintx NewSize                                  := 1572864
...

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”,您就会收到您发现的错误消息。你的这种情况正好是在在需要调整的界限边缘了。

java -XX:NewSize=1 -XX:MaxNewSize=1025k -version
java version "1.8.0_74"

java -XX:NewSize=1 -XX:MaxNewSize=1024k -version
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.

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的时候进行输出。

java -XX:NewSize=1 -XX:MaxNewSize=1023k -version
java -XX:NewSize=1 -XX:MaxNewSize=1 -version
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值