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

如果我做docker run --memory=X通过Bash脚本运行Java应用程序,有什么办法让这个Bash脚本可靠地推断有多less内存已分配给容器? 基本上,我想要这个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使用less于最大的RAM?

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

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

 > docker run --memory=64G 

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

 > cgget -nvr memory.limit_in_bytes / 68719476736 

请注意,您可能必须先通过容器图像的包pipe理器安装cgget二进制文件。 在Ubuntu上,您将需要cgroup-bin软件包。

然后你可以使用这个值来dynamic计算你的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参数仍然有一个值,尽pipe大小约为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