Java 未正确保留巨大的初始堆大小

我正在使用一台具有512GB RAM的机器(由几个AMD皓龙6212 CPU解决)。目前大约有300GB的内存可用。通过运行运行大型 Java 计算

java path/to/myApp -Xms280g -Xmx280g > output.txt

应该使Java立即保留280GB,如果失败,则出错。奇怪的是,没有发生错误,但只显示内存使用率为30.4GB,但它不会崩溃。怎么会这样?如果无法分配初始堆大小,Java难道不应该崩溃吗?top

实际上,一旦30.4GB满了,我就会得到OutOfMemory/Java堆空间/GC开销限制错误,远远早于达到280GB。使用 250GB 或 300GB 运行会产生类似的 30.3GB ~ 30.4GB 限制。我在Gentoo Linux上运行OpenJDK 64位服务器VM和OpenJDK运行时环境(IcedTea6),并且有足够的免费RAM(超过300GB)。


答案 1

参数的顺序不正确。您正在作为参数传递给您自己的程序,而不是 JVM。正确的是:-Xms280g -Xmx280g

java -Xms280g -Xmx280g path/to/myApp


答案 2

如果您希望在应用程序初始化期间抓取 -Xms 中指定的内存,请使用

java -XX:+AlwaysPreTouch -Xms2G -Xmx2G ......

AlwaysPreTouch将在JVM初始化期间要求每个内存页面,而不仅仅是将不需要的内容保留为“虚拟”。但是,请注意,这将在启动 JVM 时出现一些延迟。

使用上述开关,然后与顶部检查。您将获得JVM的完整2G(实际上更多)。


推荐