java 标记 Xms 和 Xmx 是否覆盖标记 XX:+UseCGroupMemoryLimitForHeap?

Do java flags Xms and Xmx overwrite flag XX:+UseCGroupMemoryLimitForHeap?

我是 运行 Kubernetes 中的容器化 java 应用程序。

为了让jvm根据容器规范保留内存,必须设置标志-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap

如果这两个标志与 Xms 和 Xmx 标志一起设置,jvm 的行为会是什么?一个标志会覆盖另一个吗?

例如,如果我们有 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms -Xms2500M -Xmx2500M -jar myjar.jar 在容器限制为 4Gi 的请求和 4Gi 的响应的 pod 中,在具有 128Gi 内存的主机中,JVM 将保留多少内存?

-Xmx 标志覆盖-XX:+UseCGroupMemoryLimitForHeap 标志。

标志 -XX:+UseCGroupMemoryLimitForHeap 让 JVM 检测容器中的最大堆大小应该是多少。

-Xmx 标志将最大堆大小设置为固定大小。

为了回答您的示例,JVM 将保留 2500M 堆 space。非堆和 jvm 的东西会有一些额外的内存使用。

要进一步调整容器中的内存使用情况,您可以使用 -XX:MaxRAMFraction 标志。 参见这篇文章:https://blog.csanchez.org/2017/05/31/running-a-jvm-in-a-container-without-getting-killed/

这样想, 添加 UseCGroupMemoryLimitForHeap 之前,您可以指定 Xmx 的值大于您的 pod 的值(它只会查看主机内存,而不是 pod 本身),最终被杀死。如果未指定,默认情况下为内存的 1/4。发生这种情况是因为堆的计算方式如下:

heap = memory / MaxRAMFraction

和运行:

java -XX:+PrintFlagsFinal | grep MaxRAMFraction

会显示 MaxRAMFraction = 4

现在添加了 UseCGroupMemoryLimitForHeap,您可以知道将占用 pod 本身的多少堆 。默认情况下,它仍然是 1/4;当然,您可以通过 MaxRAMFraction 进行调整。

如果您同时指定两个参数,则 Xms 获胜。总是。并且 1) 这是非常合乎逻辑的(因为 UseCGroupMemoryLimitForHeapXmx 更具体) 2) 我刚才的实验完全证明了这一点。无论指定的顺序如何,Xmx 总是获胜。

如果您是 运行 Java 8 更新 191 或更高版本,或者 Java 10、11、12、13 等,您 不能 使用 UseCGroupMemoryLimitForHeap 选项。相反,您应该使用默认激活的 UseContainerSupport

然后您可以使用以下选项控制内存,InitialRAMPercentageMaxRAMPercentageMinRAMPercentage

https://merikan.com/2019/04/jvm-in-a-container/