-XX:MaxRAMFraction=1 对容器环境中的生产安全吗?
Java 8/9 带来了对 -XX:+UseCGroupMemoryLimitForHeap
的支持(使用 -XX:+UnlockExperimentalVMOptions
).这会将 -XX:MaxRAM
设置为 cgroup 内存限制.默认情况下,JVM 分配大约 25% 的最大 RAM,因为 -XX:MaxRAMFraction
默认为 4.
Java 8/9 brought support for -XX:+UseCGroupMemoryLimitForHeap
(with -XX:+UnlockExperimentalVMOptions
). This sets -XX:MaxRAM
to the cgroup memory limit. Per default, the JVM allocates roughly 25% of the max RAM, because -XX:MaxRAMFraction
defaults to 4.
例子:
MaxRAM = 1g
MaxRAMFraction = 4
JVM is allowed to allocate: MaxRAM / MaxRAMFraction = 1g / 4 = 256m
对于(通常)由单个 JVM 进程组成的部署而言,仅使用 25% 的配额似乎是一种浪费.所以现在人们设置-XX:MaxRAMFraction=1
,所以理论上允许JVM使用100%的MaxRAM.
Using only 25% of the quota seems like waste for a deployment which (usually) consists of a single JVM process. So now people set -XX:MaxRAMFraction=1
, so the JVM is theoretically allowed to use 100% of the MaxRAM.
对于 1g 示例,这通常会导致堆大小约为 900m.这似乎有点高 - JVM 或其他东西(如远程 shell 或进程外任务)没有太多可用空间.
For the 1g example, this often results in heap sizes around 900m. This seems a bit high - there is not a lot of free room for the JVM or other stuff like remote shells or out-of-process tasks.
那么这种配置(-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1
)对于产品甚至最佳实践来说是安全的吗?还是我还是应该手动选择-Xmx
、-Xms
、-Xss
等等?
So is this configuration (-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1
) considered safe for prod or even best practice? Or should I still hand pick -Xmx
, -Xms
, -Xss
and so on?
推荐答案
我们做了一些简单的测试,结果表明设置 -XX:MaxRAM=$QUOTA
和 -XX:MaxRAMFraction=1
导致负载下的容器被杀死.JVM 分配了超过 900M 的堆,这太多了.-XX:MaxRAMFraction=2
看起来很安全(ish).
We did some simple testing which showed that setting -XX:MaxRAM=$QUOTA
and -XX:MaxRAMFraction=1
results in killed containers under load. The JVM allocates more than 900M heap, which is way too much. -XX:MaxRAMFraction=2
seems safe(ish).
请记住,您可能希望为其他进程留出空间,例如在容器中获取调试外壳 (docker exec
) 或诊断.
Keep in mind that you may want to leave headroom for other processes like getting a debug shell (docker exec
) or diagnostics in the container.
我们已经在 文章.金钱报价:
we've written up what we've learned in detail in an article. Money quotes:
TL'DR:Java 内存管理和配置仍然很复杂.尽管自 Java 9/8u131 起 JVM 可以读取 cgroup 内存限制并相应地调整内存使用,但这并不是万能的.您需要知道 -XX:+UseCGroupMemoryLimitForHeap
做了什么,并且需要为每次部署微调一些参数.否则,您可能会浪费资源和金钱,或者在最糟糕的时候杀死您的容器.-XX:MaxRAMFraction=1
特别危险.Java 10+ 带来了很多改进,但仍然需要手动配置.为了安全起见,请对您的东西进行负载测试.
TL'DR: Java memory management and configuration is still complex. Although the JVM can read cgroup memory limits and adapt memory usage accordingly since Java 9/8u131, it’s not a golden bullet. You need to know what
-XX:+UseCGroupMemoryLimitForHeap
does and you need to fine tune some parameters for every deployment. Otherwise you risk wasting resources and money or getting your containers killed at the worst time possible.-XX:MaxRAMFraction=1
is especially dangerous. Java 10+ brings a lot of improvements but still needs manual configuration. To be safe, load test your stuff.
和
最优雅的解决方案是升级到 Java 10+.Java 10 弃用了 -XX:+UseCGroupMemoryLimitForHeap
(11) 并引入了取代它的 -XX:+UseContainerSupport
(12).它还引入了 -XX:MaxRAMPercentage
(13),取值介于 0 和 100 之间.这允许对 JVM 允许分配的 RAM 量进行细粒度控制.由于 +UseContainerSupport
默认启用,所以一切都应该开箱即用.
The most elegant solution is to upgrade to Java 10+. Java 10 deprecates
-XX:+UseCGroupMemoryLimitForHeap
(11) and introduces-XX:+UseContainerSupport
(12), which supersedes it. It also introduces-XX:MaxRAMPercentage
(13) which takes a value between 0 and 100. This allows fine grained control of the amount of RAM the JVM is allowed to allocate. Since+UseContainerSupport
is enabled by default, everything should work out of the box.
编辑 #2:我们已经写了一点 关于-XX:+UseContainerSupport
Java 10 引入了 +UseContainerSupport
(默认启用),这使得 JVM 在容器环境中使用正常的默认值.自 8u191 以来,此功能已向后移植到 Java 8,这可能允许大量 Java 部署在野外正确配置其内存.
Java 10 introduced
+UseContainerSupport
(enabled by default) which makes the JVM use sane defaults in a container environment. This feature is backported to Java 8 since 8u191, potentially allowing a huge percentage of Java deployments in the wild to properly configure their memory.
相关文章