【发布时间】:2021-03-14 19:05:30
【问题描述】:
我有一个基于 Java8 OpenJDK 的 Java 应用程序。它运行在一个限制为 20GB 的 docker 容器中。
tomcat的-Xms和-Xmx设置如下:
-Xms = 60% 的容器内存(由 cgroup 指定) - 所以 12GB -Xmx = 80% 的容器内存(由 cgroup 指定) - 所以 16GB
这会在容器上留下 4GB 的空闲空间,这通常很好,但有时在负载下我看到 docker 容器退出(并且 java 进程被杀死)并出现 OOM,因为容器内存使用量已超过 20GB。
我知道 -Xmx 设置用于堆,而不是整个 Java 进程和 JVM,因此希望容器上的 4GB 'headroom' 就足够了,但似乎不是。
我知道所有用例都大相径庭,但我的问题是,一般而言,对于内存限制为 20GB 的容器而言,设置 -Xmx 设置是否太高。
我在玩弄使用 MaxRAM 设置的想法,我知道这只是决定堆内存,但我不确定这是否会产生积极影响?
您通常是使用 MaxRAM 或 -Xmx,还是同时设置两者有什么好处?
如果我使用 MaxRAM 而不是 -Xmx,java 将如何为堆分配内存?是否有一个简单的算法来解决这个问题,例如 MaxRAM 设置的 50%? java 这样做会更有效地管理内存吗?
【问题讨论】:
-
MaxHeapSize 计算为 ContainerSize * MaxRAMPercentage。默认情况下,MaxRAMPercentage 为 25(最大容器大小的 25%)。我总是设置 -XX:MaxRAMPercentage=70.0(75 或 80 太多了,一段时间后我得到了 OOM)并且从不设置 -Xmx。有了这个设置我没有任何OOM
-
@OctavianR。并非所有 JDK 8 版本都使用该逻辑
-
@OneCricketeer 感谢您的更正(我没有检查所有 JVM 的发行版),我的上述评论适用于 AdoptOpenJDK 和可能的其他发行版。如果您想检查此计算是否适用于其他 JVM,则可以列出 JVM 的标志 java -XX:+PrintFlagsFinal (for Molenpad)
-
@Octa 百分比标志在 8u192 左右被反向移植。任何早期的 JDK8 版本都没有用于任何发行版,AFAIK
-
@OneCricketeer 我明白了,(我想我记得 AdoptOpenJDK 1.8 也是这样的),那么在使用 -XX:MaxRAMPercentage 之前使用 -XX:+PrintFlagsFinal 应该可以解决这个问题。如果它不存在,那么要么使用更新版本的 JVM,要么他应该设置 -Xmx