将Java的最大堆大小(Xmx)设置为物理内存的一部分

8
JDK 8 中,默认的最大堆大小为物理内存的四分之一或1GB。您可以使用 -Xmx 开关覆盖此默认值。 Xmx 开关使用字节而不是分数。是否有一种简单直接的方法将最大堆设置为机器物理内存的 X%?为什么要这样做呢?首先是好奇心。我觉得默认的 Xmx 是根据物理内存的一部分定义的,但只要我一碰它,它就变成了一个绝对值。其次,如果我将相同(或类似)的应用程序部署到两个不同的服务器上,其中一个服务器具有更多的物理内存,我希望有自动利用额外内存的选项。这并不总是有意义的,但有时确实是这样。
明显的解决方案是使用一个检查剩余空间并计算Xmx的Shell脚本,但这似乎是一个笨拙的解决方案。我想用纯Java也应该有可能实现。

这可能是你需要在调用Java的任何地方以平台相关的方式完成的事情。 - Oliver Charlesworth
1
@OliverCharlesworth 我也是这么想的。但这很奇怪。默认值是根据物理内存的一部分定义的,但没有开关可以将1/4更改为1/3或1/2。 - Malt
由于无法更改HotSpot JVM的堆大小,因此“纯Java”解决方案是使用链接的Q&A中的技术来查找物理内存大小...然后启动新的JVM。坦率地说,您最好使用您的“笨重”解决方案。 - Stephen C
当你设置值时,通常是根据你的程序实际需要的数量来设置的。JVM并不具备这种洞察力,所以它会根据物理内存的大小进行“猜测”。不清楚的是,你作为用户是否需要去猜测。 - Arfur Narf
2个回答

13

Java 8u191 (2018年10月16日)起,有三个专用的JVM选项可控制堆大小占可用内存的比例。它们的文档在这里

请注意,与其名称所暗示的相反,MinRAMPercentage也控制着最大堆大小。

-XX:InitialRAMPercentage=percent 将JVM在应用启动时用于Java堆的初始内存量设置为最大内存量的百分比,然后再根据 -XX:MaxRAM 选项进行调整。默认值为1.5625%。
-XX:MaxRAMPercentage=percent 将JVM可用于Java堆的最大内存量设置为最大内存量的百分比,然后再根据 -XX:MaxRAM 选项进行调整。默认值为25%。
-XX:MinRAMPercentage=percent 将JVM可用于小堆(大约125 MB)的Java堆的最小内存量设置为最大内存量的百分比,然后再根据 -XX:MaxRAM 选项进行调整。默认值为50%。
以下是使用Docker在x64上使用JDK 11u10的一些示例运行情况:

docker run --memory <limit> openjdk:11 java -XX:MaxRAMPercentage=25 -XX:MinRAMPercentage=50 -XX:InitialRAMPercentage=5 -XX:+PrintFlagsFinal 2>&1 | grep HeapSize

| Memory Limit | Initial Heap Size | Max Heap Size    |
|--------------|-------------------|------------------|
| 100Mi        | 10485760 (~10%)   | 52428800 (~50%)  |
| 256Mi        | 27262976 (~10%)   | 132120576 (~50%) |
| 512Mi        | 54525952 (~10%)   | 134217728 (~25%) |
| 1Gi          | 109051904 (~10%)  | 268435456 (~25%) |

很棒的解决方案!请注意,使用OpenJDK需要版本10。https://bugs.openjdk.org/browse/JDK-8219312 快速检查:java -XX:MaxRAMPercentage=25 -version - Onnonymous

0

你可能需要自己来做。比如说你要为Windows版本进行设置,获取最大内存量(解析类似于wmic ComputerSystem get TotalPhysicalMemory的内容),计算出这个值的四分之一,并将其设置为-Xmx选项...

我想问一下,为什么你需要物理内存的百分比。最大内存量不应该影响应用程序的内存使用情况,如果有影响的话,应用程序本身应该处理。


针对“为什么需要物理内存的百分比”这个问题,举个例子,一个变量渲染距离的游戏。如果可用内存不多,则会选择小的渲染距离。但如果有大量内存可用,则可以选择更大的渲染距离。 - Richard Tingle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接