-XX:MaxRAMFraction = 1在容器环境中生产是否安全?
Java
8/9带来了对-XX:+UseCGroupMemoryLimitForHeap
(带有-XX:+UnlockExperimentalVMOptions
)的支持。这设置-XX:MaxRAM
为cgroup内存限制。默认情况下,JVM会分配大约25%的最大RAM,因为-XX:MaxRAMFraction
默认值为4。
例:
MaxRAM = 1gMaxRAMFraction = 4
JVM is allowed to allocate: MaxRAM / MaxRAMFraction = 1g / 4 = 256m
对于仅由单个JVM进程组成的部署,仅使用配额的25%似乎是浪费。因此,现在人们开始设置-XX:MaxRAMFraction=1
,因此从理论上讲,JVM可以使用MaxRAM的100%。
对于1g的示例,这通常导致堆大小约为900m。这似乎有点高-JVM或其他东西(如远程Shell或进程外任务)没有太多可用空间。
那么,此配置(-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
-XX:MaxRAMFraction=1)是否对产品甚至最佳实践来说都是安全的?或者我应该还是手拿起-Xmx
,-Xms
,-Xss
等?
回答:
我们进行了一些简单的测试,结果表明该设置-XX:MaxRAM=$QUOTA
和-XX:MaxRAMFraction=1
导致在负载下被杀死的容器。JVM分配了超过900M的堆,这太多了。-XX:MaxRAMFraction=2
似乎很安全。
请记住,您可能希望为其他过程留出空间,例如docker exec
在容器中获取调试shell()或诊断信息。
编辑:我们已经在一篇文章中写下了我们所学的内容。货币报价:
Java内存管理和配置仍然很复杂。尽管从Java 9 /
8u131开始,JVM可以读取cgroup内存限制并相应地调整内存使用量,但这并不是万灵药。您需要知道
-XX:+UseCGroupMemoryLimitForHeap
它的作用,并且需要为每个部署微调一些参数。否则,您可能会浪费资源和金钱,或者在最坏的时间杀死集装箱。-XX:MaxRAMFraction=1
尤其危险。Java10+带来了许多改进,但仍需要手动配置。为了安全起见,请对您的东西进行负载测试。
和
最优雅的解决方案是升级到Java 10+。Java
10弃用
-XX:+UseCGroupMemoryLimitForHeap
(11)并引入-XX:+UseContainerSupport
(12),以取代它。它还引入了-XX:MaxRAMPercentage
(13),其值在0到100之间。这允许对允许JVM分配的RAM数量进行精细控制。由于+UseContainerSupport
默认情况下处于启用状态,因此所有操作均应立即可用。
编辑#2:我们写了更多有关-XX:+UseContainerSupport
引入了Java 10
+UseContainerSupport
(默认情况下启用),它使JVM在容器环境中使用合理的默认值。自8u191以来,此功能已反向移植到Java8,这可能允许大量野生Java部署正确配置其内存。
以上是 -XX:MaxRAMFraction = 1在容器环境中生产是否安全? 的全部内容, 来源链接: utcz.com/qa/435635.html