Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
自动配置Java以使用分配给其Docker容器的最大RAM_Java_Bash_Docker - Fatal编程技术网

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

自动配置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用

如果我通过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用于实现资源限制。在容器内部,您可以使用该实用程序打印各种子系统(在本例中为
内存
子系统)的参数

例如,考虑一个容器的内存限制为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