Объем памяти JVM в контейнере ECS растет без ограничений - PullRequest
1 голос
/ 01 апреля 2019

Для моего определения задачи заданы следующие ограничения:

"cpu": "1024",
"memory": "8192"

Я запускаю флягу внутри контейнера докера, используя флаги cgroup "docker":

java -XX:+UseContainerSupport -XX:MaxRAMPercentage=80 -XX:InitialRAMPercentage=70 /myjar.jar foo.Main

Но ECS убивает мой сервис ошибками OOM.

Я пошел дальше и измерил использование памяти JVM и сообщил об этом из моего приложения в качестве меры отладки, используя следующее:

val bean: MemoryMXBean = ManagementFactory.getMemoryMXBean
val hmu: MemoryUsage = bean.getHeapMemoryUsage
val nhu = bean.getNonHeapMemoryUsage
... reporting these metrics ...

На изображении верхняя часть - это то, что облачные часы сообщают как использованную память. Как видите, на все 100%.

Нижний график показывает память, сообщаемую приложением:

val pc = (1.0 * hmu.getUsed) / hmu.getCommitted

Из документации:

 * Below is a picture showing an example of a memory pool:
 *
 * <pre>
 *        +----------------------------------------------+
 *        +////////////////           |                  +
 *        +////////////////           |                  +
 *        +----------------------------------------------+
 *
 *        |--------|
 *           init
 *        |---------------|
 *               used
 *        |---------------------------|
 *                  committed
 *        |----------------------------------------------|
 *                            max
    /**
     * Returns the amount of memory in bytes that is committed for
     * the Java virtual machine to use.  This amount of memory is
     * guaranteed for the Java virtual machine to use.
     *
     * @return the amount of committed memory in bytes.
     *
     */
    public long getCommitted() {
        return committed;
    };

/**
     * Returns the amount of used memory in bytes.
     *
     * @return the amount of used memory in bytes.
     *
     */
    public long getUsed() {
        return used;
    };

Мой файл Docker очень прост:

FROM openjdk:10-jdk

COPY service.jar /affinity-service.jar
COPY start.sh /start.sh
RUN chmod +x /start.sh
CMD ["/start.sh"]

и start.sh:

#!/bin/bash
set -x

OPTS=""

#... setting flags from ENV values...
#...
#...

java -XX:+UseContainerSupport -XX:MaxRAMPercentage=80 -XX:InitialRAMPercentage=70 ${OPTS} -jar /service.jar com.....Service

1 Ответ

1 голос
/ 02 апреля 2019

MaxRAMPercentage и InitialRAMPercentage флаги не ограничивают память процесса Java.
Единственное, на что влияют эти флаги, это размер кучи - см. этот ответ для подробностей.

Как я объяснил здесь , процесс Java может использовать намного больше памяти , чем размер кучи.

Плохая новость - невозможно установить ограничение жесткого диска с помощью только флагов JVM, чтобы гарантировать, что JVM никогда не будет убит ОС.Но тот же самый ответ 1019 * может дать представление о том, как анализировать объем памяти процесса Java.

...