当我运行此代码时
public static void main(String[] args) {
byte[] b = null;
for(int i=0;i<10;i++)
b = new byte[1024 * 1024];
}
在JDK7中使用JVM选项-Xmx20m -Xms20m -Xmn1m -XX:+PrintGCDetails
,将打印控制台
enter image description here。当我在JDK8中使用此JVM选项运行时,它将打印
Error occurred during initialization of VM
GC triggered before VM initialization completed. Try increasing NewSize, current value 1536K.
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.
为什么?
答案 0 :(得分:0)
错误消息包含原因。
在VM初始化完成之前触发了GC。
它与您的代码无关,因为VM初始化发生在main
运行之前。
答案 1 :(得分:0)
观察到的行为与Java 7和Java 8之间的一些变化有关。
-Xmn1024k
此选项为年轻代设置堆的initial
和maximum
大小。它是-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
...
此行为似乎与文档不符。
-Xmnsize或-XX:NewSize 设定年轻一代(托儿所)的大小。
-XX:NewSize选项相当于-Xmn。
因为-XX:NewSize=2048k
将在Java7 / 8中设置,所以JVM只选择初始大小和最大大小。
因此,如果您指定-Xmn1024k
,则实际上意味着您要设置
-XX:NewSize=1024k -XX:MaxNewSize=1024k
在Java 7中(使用1.7.0_40-b43测试),最小大小(初始和最大)为196608
。如果将值设置为低。 JVM的启动失败,带有
Error occurred during initialization of VM
Too small new size specified
在Java 8中(使用1.8.0_74-b02测试)最小大小(初始和最大)为1572864
(1536K)。
现在为什么你用Java 8获得这个NewSize (1536k) is greater than the MaxNewSize (1024k)
。
如果您选择NewSize
低于最小尺寸(1536K),则会默默调整到最小尺寸。
java -XX:+PrintFlagsFinal -XX:NewSize=1k -version | grep NewSize
...
uintx NewSize := 1572864
...
如果您选择MaxNewSize
低于NewSize
MaxNewSize
,则会默默设置为NewSize
java -XX:+PrintFlagsFinal -XX:NewSize=2048k -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 2097152
uintx NewSize := 2097152
...
如果您选择NewSize
且MaxNewSize
低于最小尺寸且MaxNewSize
大于NewSize
,则两者都设置为最小尺寸。
java -XX:+PrintFlagsFinal -XX:NewSize=1024k -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 1572864
uintx NewSize := 1572864
...
这甚至适用于NewSize
java -XX:+PrintFlagsFinal -XX:NewSize=1 -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 1572864
uintx NewSize := 1572864
...
但是,一旦您为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.
这解释了为什么java -Xmn1025k -version
在java -Xmn1024k -version
为您提供错误消息时正常运行。
编辑经过多次测试。仅在MaxNewSize
等于1024k
的情况下才会打印错误。接下来的示例使用NewSize
和MaxNewSize
的默认大小。
java -XX:NewSize=1 -XX:MaxNewSize=1023k -version
java -XX:NewSize=1 -XX:MaxNewSize=1 -version