当前位置:  开发笔记 > 编程语言 > 正文

自动配置Java以使用分配给其Docker容器的最大RAM

如何解决《自动配置Java以使用分配给其Docker容器的最大RAM》经验,为你挑选了1个好方法。

如果我docker run --memory=X通过Bash脚本运行Java应用程序,有没有办法让这个Bash脚本可靠地推断已分配给容器的内存量?基本上,我希望这个Bash脚本执行以下操作:

#!/bin/bash

# (Do some other stuff...)

MAX_RAM="$(get-max-ram)"
exec java "-Xms${MAX_RAM}" "-Xmx${MAX_RAM}" -jar my_jar.jar

另外,如果我这样做,我应该让Java使用比最大RAM少一点吗?



1> helmbert..:

Docker使用cgroup来实现资源限制.在容器内部,您可以使用该cgget实用程序来打印各种子系统的参数(在本例中为memory子系统).

例如,考虑一个内存限制为64G的容器(毕竟它是Java):

> docker run --memory=64G

在容器内,然后用于cgget读取memory.limit_in_bytes参数的当前值:

> cgget -nvr memory.limit_in_bytes /
68719476736

请注意,您可能必须首先cgget通过容器映像的包管理器安装二进制文件.在Ubuntu上,你需要这个cgroup-bin包.

然后,您可以使用此值动态计算JVM参数(仅作为示例,根据您自己的需要进行调整):

MAX_RAM=$(cgget -nvr memory.limit_in_bytes /)
JVM_MIN_HEAP=$(printf "%.0f" $(echo "${MAX_RAM} * 0.2" | bc))
JVM_MAX_HEAP=$(printf "%.0f" $(echo "${MAX_RAM} * 0.8" | bc))
exec java "-Xms${JVM_MIN_HEAP}" "-Xmx${JVM_MAX_HEAP}" -jar my_jar.jar

重要:当没有内存限制(即没有--memory=X标志)运行时,memory.limit_in_bytes参数仍然会有一个值,尽管大小约为2 ^ 63 - 4096:

> cgget -nvr memory.limit_in_bytes /
9223372036854771712

除非您想以最小堆空间大约8 EB启动JVM,否则您的入口点脚本也应该考虑这种情况:

MAX_RAM=$(cgget -nvr memory.limit_in_bytes /)
if [ $MAX_RAM -le 137438953472 ] ; then
    JVM_MIN_HEAP=$(printf "%.0f" $(echo "${MAX_RAM} * 0.2" | bc))
    JVM_MAX_HEAP=$(printf "%.0f" $(echo "${MAX_RAM} * 0.8" | bc))
else
    JVM_MIN_HEAP=32G
    JVM_MAX_HEAP=128G
fi

exec java "-Xms${JVM_MIN_HEAP}" "-Xmx${JVM_MAX_HEAP}" -jar my_jar.jar


在您的示例中没有明确地调出它.但是,您是否将max和min乘以小于容器,以便JVM可以在容器可能退出之前处理OOM情况?
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有