Docker używa cgroups do realizacji limitów zasobów. Wewnątrz kontenera można użyć narzędzia cgget
, aby wydrukować parametry różnych podsystemów (w tym przypadku podsystemu memory
).
Rozważmy na przykład pojemnik zaczął z limitem pamięci 64G (to jest Java, po wszystkich):
> docker run --memory=64G
w pojemniku, a następnie użyć cgget
aby odczytać aktualną wartość parametru memory.limit_in_bytes
:
> cgget -nvr memory.limit_in_bytes/
68719476736
Pamiętaj, że prawdopodobnie będziesz musiał najpierw zainstalować plik binarny cgget
za pośrednictwem menedżera pakietów obrazu kontenera. W systemie Ubuntu potrzebny jest pakiet cgroup-bin
.
można następnie użyć tej wartości do dynamicznie obliczyć parametry JVM (tylko jako przykład, dostosować do własnych potrzeb):
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
Ważne: Kiedy uruchomić bez ograniczeń pamięci (tj bez --memory=X
flagi), parametr memory.limit_in_bytes
nadal mają wartości, ale o wielkości około 2^63 - 4096:
> cgget -nvr memory.limit_in_bytes/
9223372036854771712
Jeśli nie chcesz, aby uruchomić JVM o minimalnej przestrzeni sterty około 8 EB skrypt punkt_wejścia powinny również rozważyć tę sprawę:
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
Nie zapomnij o PermSize;) (Wtedy nie używać maksymalnej RAM ..) –
@ Gaël permsize nie ma znaczenia, ponieważ Java 8. – Gimby
Rzeczywiście, zależy to od wersji Java. Dzięki za tę precyzję. –