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) 这是非常合乎逻辑的(因为 UseCGroupMemoryLimitForHeap
比 Xmx
更具体) 2) 我刚才的实验完全证明了这一点。无论指定的顺序如何,Xmx
总是获胜。
如果您是 运行 Java 8 更新 191 或更高版本,或者 Java 10、11、12、13 等,您 不能 使用 UseCGroupMemoryLimitForHeap
选项。相反,您应该使用默认激活的 UseContainerSupport
。
然后您可以使用以下选项控制内存,InitialRAMPercentage
、MaxRAMPercentage
和 MinRAMPercentage
。
我是 运行 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) 这是非常合乎逻辑的(因为 UseCGroupMemoryLimitForHeap
比 Xmx
更具体) 2) 我刚才的实验完全证明了这一点。无论指定的顺序如何,Xmx
总是获胜。
如果您是 运行 Java 8 更新 191 或更高版本,或者 Java 10、11、12、13 等,您 不能 使用 UseCGroupMemoryLimitForHeap
选项。相反,您应该使用默认激活的 UseContainerSupport
。
然后您可以使用以下选项控制内存,InitialRAMPercentage
、MaxRAMPercentage
和 MinRAMPercentage
。