Automatically configure Java to use the maximum RAM allocated for its Docker container

If I execute docker run --memory=X to run a Java application through a Bash script, is there a way to get this Bash script before reliable output , how much memory has been allocated to the container? Basically, I want this Bash script to do something like:

 #!/bin/bash # (Do some other stuff...) MAX_RAM="$(get-max-ram)" exec java "-Xms${MAX_RAM}" "-Xmx${MAX_RAM}" -jar my_jar.jar 

Also, if I do higher, should I use Java a little less than the maximum RAM?

+5
source share
1 answer

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 
+5
source

Source: https://habr.com/ru/post/1239800/


All Articles