Docker uses cgroups to implement resource restrictions. Inside the container, you can use the cgget utility to print the parameters of various subsystems (in this case, the memory subsystem).
For example, consider a container running with a 64G memory limit (this is Java, after all):
> docker run --memory=64G
Inside the container, use cgget to read the current value of the memory.limit_in_bytes parameter:
> cgget -nvr memory.limit_in_bytes / 68719476736
Note that you may have to install the cgget binary cgget through the container image package manager. On Ubuntu, you will need the cgroup-bin package.
Then you can use this value to dynamically calculate JVM parameters (as an example, adapt to your own needs):
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
It is important . When launched without memory limitation (i.e., without the --memory=X flag), the memory.limit_in_bytes parameter will still have a value, although the value is about 2 ^ 63-4096:
> cgget -nvr memory.limit_in_bytes / 9223372036854771712
If you don't want to run the JVM with a minimum heap of around 8 EB, your script entry point should also consider this case:
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