自动配置Java以使用分配给其Docker容器的最大RAM
如果我通过Bash脚本运行Java应用程序,那么有没有办法让这个Bash脚本可靠地推断出容器分配了多少内存?基本上,我希望这个Bash脚本可以执行以下操作:自动配置Java以使用分配给其Docker容器的最大RAM,java,bash,docker,Java,Bash,Docker,如果我通过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少一点?Docker用
#!/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少一点?Docker用于实现资源限制。在容器内部,您可以使用该实用程序打印各种子系统(在本例中为内存
子系统)的参数
例如,考虑一个容器的内存限制为64 G(毕竟是java):
在容器中,然后使用cgget
读取内存的当前值。以字节为单位限制参数:
> cgget -nvr memory.limit_in_bytes /
68719476736
请注意,您可能必须首先通过容器映像的包管理器安装cgget
二进制文件。在Ubuntu上,您需要cgroupbin
包
然后可以使用该值动态计算JVM参数(例如,根据自己的需要进行调整):
重要:在没有内存限制(即没有--memory=X
标志)的情况下运行时,内存.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
- java5/6/7/8u131-:一种简单但有效的方法,您可以使用
java-Xmx cat/sys/fs/cgroup/memory/memory.limit_in_bytes
(windows除外)
- java8u131+和java9+:
-XX:+UnlockExperimentalVMOptions-XX:+UseCGroupMemoryLimitForHeap
将完成此任务
- 默认情况下,java 8u191+:
UseContainerSupport
处于启用状态。这个特性是从java10向后移植的,但到目前为止还没有向后移植到java9
- java10+:
UseContainerSupport
默认情况下处于启用状态
参考:
不要忘记PermSize;)(那么就不要使用最大RAM.)@Gaël permsize是不相关的,因为Java 8。实际上,这取决于您的Java版本。谢谢你这么精确。说得好,谢谢!顺便说一句,我使用的是Java7。在您的示例中,可能没有显式调用它的副本。但是,您是否将最大值和最小值相乘,使其小于容器,以便JVM能够在容器可能退出之前处理OOM情况?作为回退,我将使用此答案中的最小值limit_(以字节为单位)
,以及/proc/meminfo
> cgget -nvr memory.limit_in_bytes /
9223372036854771712
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