JVM内存增长超出ECS容器中的限制

时间:2019-04-01 18:54:00

标签: java docker jvm amazon-ecs

我的任务定义配置有以下限制:

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

我正在使用“ docker” cgroup标志在docker容器中运行jar:

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 个答案:

答案 0 :(得分:1)

MaxRAMPercentageInitialRAMPercentage标志不会限制Java进程的内存。
这些标志唯一影响的是堆大小-有关详细信息,请参见this answer

正如我所解释的here,Java进程可以使用比堆大小大得多的内存。

坏消息是-仅通过JVM标志来设置硬盘内存限制是不可能的,以确保JVM不会被操作系统杀死。但是same answer可能会给出一个想法,如何分析Java进程的内存占用量。