Java JDK7 JVM与JDK8不同
当我运行此代码时Java JDK7 JVM与JDK8不同,java,jvm,Java,Jvm,当我运行此代码时 public static void main(String[] args) { byte[] b = null; for(int i=0;i<10;i++) b = new byte[1024 * 1024]; } 为什么?错误消息包含原因 在VM初始化完成之前触发GC 它与您的代码无关,因为VM初始化发生在main运行之前。观察到的行为与Java 7和Java 8之间的某些更改有关 -Xmn1024k 此选项设置年轻一代堆的初始和最大
public static void main(String[] args) {
byte[] b = null;
for(int i=0;i<10;i++)
b = new byte[1024 * 1024];
}
为什么?错误消息包含原因 在VM初始化完成之前触发GC
它与您的代码无关,因为VM初始化发生在
main
运行之前。观察到的行为与Java 7和Java 8之间的某些更改有关
-Xmn1024k
此选项设置年轻一代堆的初始
和最大
大小。它是-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
因为在Java7/8中,-XX:NewSize=2048k
只设置初始大小和最大大小,由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)
现在,为什么在Java8中,NewSize(1536k)大于MaxNewSize(1024k)
如果选择小于最小大小(1536K)的NewSize
,它会自动调整为该最小大小
java -XX:+PrintFlagsFinal -XX:NewSize=1k -version | grep NewSize
...
uintx NewSize := 1572864
...
java -XX:+PrintFlagsFinal -XX:NewSize=1024k -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 1572864
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
...
java -XX:+PrintFlagsFinal -XX:NewSize=1 -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 1572864
uintx NewSize := 1572864
...
如果选择NewSize
和MaxNewSize
小于最小大小和MaxNewSize
大于NewSize
,则两者都设置为最小大小
java -XX:+PrintFlagsFinal -XX:NewSize=1k -version | grep NewSize
...
uintx NewSize := 1572864
...
java -XX:+PrintFlagsFinal -XX:NewSize=1024k -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 1572864
uintx NewSize := 1572864
...
这甚至适用于NewSize
java -XX:+PrintFlagsFinal -XX:NewSize=2048k -XX:MaxNewSize=1025k -version | \
grep NewSize
...
uintx MaxNewSize := 2097152
uintx NewSize := 2097152
...
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
运行良好,而asjava-Xmn1024k-version
会给出错误消息
在进行更多测试后编辑。只有当MaxNewSize
等于1024k
时,才会打印错误。下面的示例使用的是NewSize
和MaxNewSize
的默认大小
java -XX:NewSize=1 -XX:MaxNewSize=1023k -version
java -XX:NewSize=1 -XX:MaxNewSize=1 -version
因为JDK8不同于JDK7。还有,你为什么把内存限制设置得这么低?因为我试图将所有新创建的对象分配给老一代。所以我发现这段代码在JAVA8中无法运行。是什么导致代码在JAVA7上运行而不是在JAVA8中运行?不要在这里发布文本图片。张贴文本。