Memory limits detection by java process (Fargate)

0

I'm trying to take advantage of the feature that allows java process to detect what is the memory limit set for a given container run. (Container Awareness)

I'm using java version 8u192b12 that allows to use the following VM options without the need of (-XX:+UseContainerSupport)

-XX:InitialRAMPercentage=50.0 
-XX:MaxRAMPercentage=90.0 

That should set the max memory allocation for a java process to 90% of what the container is allowed to take.
Here's my test class

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.RuntimeMXBean;

public class Check {
    public static void main(String[] args) {
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        System.out.println("heap: " + memoryBean.getHeapMemoryUsage());
        System.exit(0);
    }
}

with java -XX:InitialRAMPercentage=50.0 -XX:MaxRAMPercentage=90.0 MyClass

This works as expected locally when I run my container with docker:
docker run -m=256M img

heap init = 134217728(131072K),... max = 243269632(237568K)
docker run -m=512M img
heap init = 268435456(262144K), ...max = 484442112(473088K)

but when I execute the same using Fargate(Platform 1.3) with task mem limit of 512MB

I get:

heap: init = 1971322880(1925120K) ...max = 3546284032(3463168K)
with 1GB
heap: init = 1971322880(1925120K) max = 3546284032(3463168K)

Is AWS ECS Farget using that docker -m switch for memory restriction or something custom?
I'm using Docker version 18.09.0 locally.

Edited by: kubakuba on Jan 22, 2019 2:58 AM

Edited by: kubakuba on Feb 27, 2019 3:54 AM

asked 5 years ago3766 views
1 Answer
1

Thx for posting - you likely already have solved it but for other googlers that might reach this post I'll go with my similar problem and solution.

My jvm based service was allocated to much heap memory: 6.3G

I have these jvm args: -XX:+UseContainerSupport -XX:MaxRAMPercentage=80.0

Using the amazoncorretto:8u232 to my understanding a modern java 8 with back-ported docker features so this documentation should hold: https://www.eclipse.org/openj9/docs/xxusecontainersupport

For me the solution was to add the Memory setting on both the task and the container for example this cloudformation snippet - based on https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html:

    "Resources": {
        "Task": {
            "Properties": {
                "RequiresCompatibilities": ["FARGATE"],
                "NetworkMode": "awsvpc",
                "ExecutionRoleArn": "<some role>",
                "Cpu": 1024,
                "Memory": 2048,
                "ContainerDefinitions": [
                    {
                        "Memory": 1792,
                        "Essential": true,
                        "Image": { "Fn::Join" : [ ":", [ "<service-docker-image>", { "Ref": "ImageTag" } ] ] },
                        ... 
                   }, 
                    {
                        "Memory": 256,
                        "Essential": true,
                        "Image": { "Fn::Join" : [ ":", [ "<service-docker-nginx-proxy>", { "Ref": "ImageTag" } ] ] },
                        ...

and with this the java service logs memory consumption:

heap memory usage: init = 29360128(28672K) used = 1081712776(1056360K) committed = 1162170368(1134932K) max = 1636040704(1597696K)

Roughly 1.6G for the heap which sounds sound.

Edited by: pellekrogholt on Jan 3, 2020 4:07 AM

Edited by: pellekrogholt on Jan 3, 2020 4:07 AM

answered 4 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions